o b$@sdZddlmZddlmZddlmZmZddlmZGdddZ Gdd d eZ ee Gd d d Z Gd d d e Z Gddde Z GdddejZGdddeZGdddZdS)a Hierarchical Token Bucket traffic shaping. Patterned after U{Martin Devera's Hierarchical Token Bucket traffic shaper for the Linux kernel}. @seealso: U{HTB Linux queuing discipline manual - user guide } @seealso: U{Token Bucket Filter in Linux Advanced Routing & Traffic Control HOWTO} )time)Optional) Interface implementer)pcpc@sPeZdZUdZdZeeed<dZeeed<dZ d ddZ dd Z d d Z dS) Bucketa 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 L{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 L{None}, the bucket drains instantaneously. @type rate: C{int} NmaxburstratercCsd|_||_t|_dS)a( 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} rN)content parentBucketrlastDrip)selfr r7/usr/lib/python3/dist-packages/twisted/protocols/htb.py__init__3s  zBucket.__init__cCsR||jdur |}n t||j|j}|jdur |j|}|j|7_|S)at 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} N)driprminr r add)r amount allowablerrrr@s   z Bucket.addcCsb|jdur |j|jdurd|_nt}||j}||j}td|j||_||_|jdkS)z 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} Nr)r rr r rr max)r now deltaTime deltaTokensrrrrXs     z Bucket.dripN) __name__ __module__ __qualname____doc__rrint__annotations__r _refcountrrrrrrrrs   rc@seZdZddZdS) IBucketFiltercOdS)zn Return a L{Bucket} corresponding to the provided parameters. @returntype: L{Bucket} Nr) somethingssome_kwrrr getBucketForqszIBucketFilter.getBucketForN)rrrr&rrrrr"ps r"c@sHeZdZUdZeZdZeee d<d ddZ ddZ dd Z d d Z dS) HierarchicalBucketFilterz 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} N sweepIntervalcCsi|_||_t|_dSr)buckets parentFilterr lastSweep)r r*rrrrs z!HierarchicalBucketFilter.__init__cOs|jdurt|j|jkr||jr#|jj|g|Ri|}nd}|j|i|}|j|}|durA| |}||j|<|S)z 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} N) r(rr+sweepr*r& getBucketKeyr)get bucketFactory)r akwr keybucketrrrr&s    z%HierarchicalBucketFilter.getBucketForcOr#)a% 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. Nr)r r0r1rrrr-s z%HierarchicalBucketFilter.getBucketKeycCs>|jD]\}}|}|jdkr|r|j|=qt|_dS)z' Remove empty buckets. rN)r)itemsrr!rr+)r r2r3bucket_is_emptyrrrr,s  zHierarchicalBucketFilter.sweepr)rrrrrr/r(rrr rr&r-r,rrrrr'ys    r'c@eZdZdZdZddZdS) FilterByHostzF A Hierarchical Bucket filter with a L{Bucket} for each host. icC |dSN)getPeerr transportrrrr- zFilterByHost.getBucketKeyNrrrrr(r-rrrrr7 r7c@seZdZdZdZddZdS)FilterByServerzI A Hierarchical Bucket filter with a L{Bucket} for each service. NcCr8)N)getHostr<rrrr-r>zFilterByServer.getBucketKeyr?rrrrrAr@rAc@s,eZdZdZdZddZddZddZd S) ShapedConsumerzL Wraps a C{Consumer} and shapes the rate at which it receives data. FcCs(tj||||_|jjd7_dSr9)rProducerConsumerProxyrr3r!)r consumerr3rrrrszShapedConsumer.__init__cCs&|jt|}tj||d|Sr)r3rlenrrE_writeSomeData)r datarrrrrHszShapedConsumer._writeSomeDatacCs tj||jjd8_dSr9)rrE stopProducingr3r!)r rrrrJs zShapedConsumer.stopProducingN)rrrr iAmStreamingrrHrJrrrrrDs  rDc@r6)ShapedTransportaR 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}). FcCs t|j|Sr)getattrrF)r namerrr __getattr__s zShapedTransport.__getattr__N)rrrrrKrOrrrrrLs rLc@s eZdZdZddZddZdS)ShapedProtocolFactorya 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}. cCs||_||_dS)a 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} class @param bucketFilter: The filter which will determine how traffic is shaped. @type bucketFilter: L{HierarchicalBucketFilter}. N)protocol bucketFilter)r protoClassrRrrrrs zShapedProtocolFactory.__init__cs.j|i|}|jfdd}||_|S)z 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}. csj|}t||}|Sr)rRr&rL)r=r3shapedTransportorigMakeConnectionr rrmakeConnection,s  z6ShapedProtocolFactory.__call__..makeConnection)rQrW)r r0r1protorWrrUr__call__!s zShapedProtocolFactory.__call__N)rrrrrrYrrrrrPs rPN)rrtypingrzope.interfacerrtwisted.protocolsrrr"r'r7rArErDrLrPrrrrs   R C