aboutsummaryrefslogtreecommitdiffstats
path: root/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/protocols/htb.py
diff options
context:
space:
mode:
Diffstat (limited to 'lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/protocols/htb.py')
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/protocols/htb.py297
1 files changed, 0 insertions, 297 deletions
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/protocols/htb.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/protocols/htb.py
deleted file mode 100755
index 10008cf4..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/protocols/htb.py
+++ /dev/null
@@ -1,297 +0,0 @@
-# -*- test-case-name: twisted.test.test_htb -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-
-"""
-Hierarchical Token Bucket traffic shaping.
-
-Patterned after U{Martin Devera's Hierarchical Token Bucket traffic
-shaper for the Linux kernel<http://luxik.cdi.cz/~devik/qos/htb/>}.
-
-@seealso: U{HTB Linux queuing discipline manual - user guide
- <http://luxik.cdi.cz/~devik/qos/htb/manual/userg.htm>}
-@seealso: U{Token Bucket Filter in Linux Advanced Routing & Traffic Control
- HOWTO<http://lartc.org/howto/lartc.qdisc.classless.html#AEN682>}
-"""
-
-
-# TODO: Investigate whether we should be using os.times()[-1] instead of
-# time.time. time.time, it has been pointed out, can go backwards. Is
-# the same true of os.times?
-from time import time
-from zope.interface import implements, Interface
-
-from twisted.protocols import pcp
-
-
-class Bucket:
- """
- Implementation of a Token bucket.
-
- A bucket can hold a certain number of tokens and it drains over time.
-
- @cvar maxburst: The maximum number of tokens that the bucket can
- hold at any given time. If this is C{None}, the bucket has
- an infinite size.
- @type maxburst: C{int}
- @cvar rate: The rate at which the bucket drains, in number
- of tokens per second. If the rate is C{None}, the bucket
- drains instantaneously.
- @type rate: C{int}
- """
-
- maxburst = None
- rate = None
-
- _refcount = 0
-
- def __init__(self, parentBucket=None):
- """
- Create a L{Bucket} that may have a parent L{Bucket}.
-
- @param parentBucket: If a parent Bucket is specified,
- all L{add} and L{drip} operations on this L{Bucket}
- will be applied on the parent L{Bucket} as well.
- @type parentBucket: L{Bucket}
- """
- self.content = 0
- self.parentBucket = parentBucket
- self.lastDrip = time()
-
-
- def add(self, amount):
- """
- Adds tokens to the L{Bucket} and its C{parentBucket}.
-
- This will add as many of the C{amount} tokens as will fit into both
- this L{Bucket} and its C{parentBucket}.
-
- @param amount: The number of tokens to try to add.
- @type amount: C{int}
-
- @returns: The number of tokens that actually fit.
- @returntype: C{int}
- """
- self.drip()
- if self.maxburst is None:
- allowable = amount
- else:
- allowable = min(amount, self.maxburst - self.content)
-
- if self.parentBucket is not None:
- allowable = self.parentBucket.add(allowable)
- self.content += allowable
- return allowable
-
-
- def drip(self):
- """
- Let some of the bucket drain.
-
- The L{Bucket} drains at the rate specified by the class
- variable C{rate}.
-
- @returns: C{True} if the bucket is empty after this drip.
- @returntype: C{bool}
- """
- if self.parentBucket is not None:
- self.parentBucket.drip()
-
- if self.rate is None:
- self.content = 0
- else:
- now = time()
- deltaTime = now - self.lastDrip
- deltaTokens = deltaTime * self.rate
- self.content = max(0, self.content - deltaTokens)
- self.lastDrip = now
- return self.content == 0
-
-
-class IBucketFilter(Interface):
- def getBucketFor(*somethings, **some_kw):
- """
- Return a L{Bucket} corresponding to the provided parameters.
-
- @returntype: L{Bucket}
- """
-
-class HierarchicalBucketFilter:
- """
- Filter things into buckets that can be nested.
-
- @cvar bucketFactory: Class of buckets to make.
- @type bucketFactory: L{Bucket}
- @cvar sweepInterval: Seconds between sweeping out the bucket cache.
- @type sweepInterval: C{int}
- """
-
- implements(IBucketFilter)
-
- bucketFactory = Bucket
- sweepInterval = None
-
- def __init__(self, parentFilter=None):
- self.buckets = {}
- self.parentFilter = parentFilter
- self.lastSweep = time()
-
- def getBucketFor(self, *a, **kw):
- """
- Find or create a L{Bucket} corresponding to the provided parameters.
-
- Any parameters are passed on to L{getBucketKey}, from them it
- decides which bucket you get.
-
- @returntype: L{Bucket}
- """
- if ((self.sweepInterval is not None)
- and ((time() - self.lastSweep) > self.sweepInterval)):
- self.sweep()
-
- if self.parentFilter:
- parentBucket = self.parentFilter.getBucketFor(self, *a, **kw)
- else:
- parentBucket = None
-
- key = self.getBucketKey(*a, **kw)
- bucket = self.buckets.get(key)
- if bucket is None:
- bucket = self.bucketFactory(parentBucket)
- self.buckets[key] = bucket
- return bucket
-
- def getBucketKey(self, *a, **kw):
- """
- Construct a key based on the input parameters to choose a L{Bucket}.
-
- The default implementation returns the same key for all
- arguments. Override this method to provide L{Bucket} selection.
-
- @returns: Something to be used as a key in the bucket cache.
- """
- return None
-
- def sweep(self):
- """
- Remove empty buckets.
- """
- for key, bucket in self.buckets.items():
- bucket_is_empty = bucket.drip()
- if (bucket._refcount == 0) and bucket_is_empty:
- del self.buckets[key]
-
- self.lastSweep = time()
-
-
-class FilterByHost(HierarchicalBucketFilter):
- """
- A Hierarchical Bucket filter with a L{Bucket} for each host.
- """
- sweepInterval = 60 * 20
-
- def getBucketKey(self, transport):
- return transport.getPeer()[1]
-
-
-class FilterByServer(HierarchicalBucketFilter):
- """
- A Hierarchical Bucket filter with a L{Bucket} for each service.
- """
- sweepInterval = None
-
- def getBucketKey(self, transport):
- return transport.getHost()[2]
-
-
-class ShapedConsumer(pcp.ProducerConsumerProxy):
- """
- Wraps a C{Consumer} and shapes the rate at which it receives data.
- """
- # Providing a Pull interface means I don't have to try to schedule
- # traffic with callLaters.
- iAmStreaming = False
-
- def __init__(self, consumer, bucket):
- pcp.ProducerConsumerProxy.__init__(self, consumer)
- self.bucket = bucket
- self.bucket._refcount += 1
-
- def _writeSomeData(self, data):
- # In practice, this actually results in obscene amounts of
- # overhead, as a result of generating lots and lots of packets
- # with twelve-byte payloads. We may need to do a version of
- # this with scheduled writes after all.
- amount = self.bucket.add(len(data))
- return pcp.ProducerConsumerProxy._writeSomeData(self, data[:amount])
-
- def stopProducing(self):
- pcp.ProducerConsumerProxy.stopProducing(self)
- self.bucket._refcount -= 1
-
-
-class ShapedTransport(ShapedConsumer):
- """
- Wraps a C{Transport} and shapes the rate at which it receives data.
-
- This is a L{ShapedConsumer} with a little bit of magic to provide for
- the case where the consumer it wraps is also a C{Transport} and people
- will be attempting to access attributes this does not proxy as a
- C{Consumer} (e.g. C{loseConnection}).
- """
- # Ugh. We only wanted to filter IConsumer, not ITransport.
-
- iAmStreaming = False
- def __getattr__(self, name):
- # Because people will be doing things like .getPeer and
- # .loseConnection on me.
- return getattr(self.consumer, name)
-
-
-class ShapedProtocolFactory:
- """
- Dispense C{Protocols} with traffic shaping on their transports.
-
- Usage::
-
- myserver = SomeFactory()
- myserver.protocol = ShapedProtocolFactory(myserver.protocol,
- bucketFilter)
-
- Where C{SomeServerFactory} is a L{twisted.internet.protocol.Factory}, and
- C{bucketFilter} is an instance of L{HierarchicalBucketFilter}.
- """
- def __init__(self, protoClass, bucketFilter):
- """
- Tell me what to wrap and where to get buckets.
-
- @param protoClass: The class of C{Protocol} this will generate
- wrapped instances of.
- @type protoClass: L{Protocol<twisted.internet.interfaces.IProtocol>}
- class
- @param bucketFilter: The filter which will determine how
- traffic is shaped.
- @type bucketFilter: L{HierarchicalBucketFilter}.
- """
- # More precisely, protoClass can be any callable that will return
- # instances of something that implements IProtocol.
- self.protocol = protoClass
- self.bucketFilter = bucketFilter
-
- def __call__(self, *a, **kw):
- """
- Make a C{Protocol} instance with a shaped transport.
-
- Any parameters will be passed on to the protocol's initializer.
-
- @returns: A C{Protocol} instance with a L{ShapedTransport}.
- """
- proto = self.protocol(*a, **kw)
- origMakeConnection = proto.makeConnection
- def makeConnection(transport):
- bucket = self.bucketFilter.getBucketFor(transport)
- shapedTransport = ShapedTransport(transport, bucket)
- return origMakeConnection(shapedTransport)
- proto.makeConnection = makeConnection
- return proto