
    h$                        S r SSKJr  SSKJr  SSKJrJr  SSKJr   " S S5      r	 " S S	\5      r
\" \
5       " S
 S5      5       r " S S\5      r " S S\5      r " S S\R                  5      r " S S\5      r " S S5      rg)a  
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>}
    )time)Optional)	Interfaceimplementer)pcpc                   \    \ rS rSr% SrSr\\   \S'   Sr	\\   \S'   Sr
SS jrS rS	 rS
rg)Bucket   a  
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}
Nmaxburstrater   c                 <    SU l         Xl        [        5       U l        g)z
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}
r   N)contentparentBucketr   lastDrip)selfr   s     \/root/1688_scrapy/alibaba-scraper/venv/lib/python3.13/site-packages/twisted/protocols/htb.py__init__Bucket.__init__3   s     (    c                    U R                  5         U R                  c  UnO"[        XR                  U R                  -
  5      nU R                  b  U R                  R                  U5      nU =R                  U-  sl        U$ )a4  
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}
)dripr   minr   r   add)r   amount	allowables      r   r   
Bucket.add@   si     			== IFMMDLL$@AI())--i8I	!r   c                 ,   U R                   b  U R                   R                  5         U R                  c  SU l        OJ[	        5       nXR
                  -
  nX R                  -  n[        SU R                  U-
  5      U l        Xl        U R                  S:H  $ )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}
r   )r   r   r   r   r   r   max)r   now	deltaTimedeltaTokenss       r   r   Bucket.dripX   s}     (""$99DL&Cmm+I#ii/Kq$,,"<=DLM||q  r   )r   r   r   N)__name__
__module____qualname____firstlineno____doc__r   r   int__annotations__r   	_refcountr   r   r   __static_attributes__ r   r   r	   r	      s9     #Hhsm"D(3-I0!r   r	   c                       \ rS rSrS rSrg)IBucketFilterp   c                      g)zV
Return a L{Bucket} corresponding to the provided parameters.

@returntype: L{Bucket}
Nr-   )
somethingssome_kws     r   getBucketForIBucketFilter.getBucketForq   s    r   r-   N)r$   r%   r&   r'   r4   r,   r-   r   r   r/   r/   p   s    r   r/   c                   N    \ rS rSr% Sr\rSr\\	   \
S'   S
S jrS rS rS rS	rg)HierarchicalBucketFiltery   z
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sweepIntervalc                 <    0 U l         Xl        [        5       U l        g r#   )bucketsparentFilterr   	lastSweep)r   r<   s     r   r   !HierarchicalBucketFilter.__init__   s    (r   c                    U R                   b5  [        5       U R                  -
  U R                   :  a  U R                  5         U R                  (       a!  U R                  R
                  " U /UQ70 UD6nOSnU R                  " U0 UD6nU R                  R                  U5      nUc  U R                  U5      nXPR                  U'   U$ )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)
r9   r   r=   sweepr<   r4   getBucketKeyr;   getbucketFactory)r   akwr   keybuckets         r   r4   %HierarchicalBucketFilter.getBucketFor   s     *Vdnn$(:(::JJL,,99$IIbILL)b)!!#&>''5F &LLr   c                     g)z
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   rD   rE   s      r   rA   %HierarchicalBucketFilter.getBucketKey   s     r   c                     U R                   R                  5        H=  u  pUR                  5       nUR                  S:X  d  M'  U(       d  M0  U R                   U	 M?     [	        5       U l        g)z
Remove empty buckets.
r   N)r;   itemsr   r+   r   r=   )r   rF   rG   bucket_is_emptys       r   r@   HierarchicalBucketFilter.sweep   sQ      <<--/KC$kkmO  A%??LL% 0
 r   )r;   r=   r<   r#   )r$   r%   r&   r'   r(   r	   rC   r9   r   r)   r*   r   r4   rA   r@   r,   r-   r   r   r7   r7   y   s0     M#'M8C=' 
4		 r   r7   c                   "    \ rS rSrSrSrS rSrg)FilterByHost   z>
A Hierarchical Bucket filter with a L{Bucket} for each host.
i  c                 (    UR                  5       S   $ N   )getPeerr   	transports     r   rA   FilterByHost.getBucketKey         "1%%r   r-   Nr$   r%   r&   r'   r(   r9   rA   r,   r-   r   r   rP   rP      s     M&r   rP   c                   "    \ rS rSrSrSrS rSrg)FilterByServer   zA
A Hierarchical Bucket filter with a L{Bucket} for each service.
Nc                 (    UR                  5       S   $ )N   )getHostrV   s     r   rA   FilterByServer.getBucketKey   rY   r   r-   rZ   r-   r   r   r\   r\      s     M&r   r\   c                   .    \ rS rSrSrSrS rS rS rSr	g)	ShapedConsumer   zD
Wraps a C{Consumer} and shapes the rate at which it receives data.
Fc                     [         R                  R                  X5        X l        U R                  =R                  S-  sl        g rS   )r   ProducerConsumerProxyr   rG   r+   )r   consumerrG   s      r   r   ShapedConsumer.__init__   s0    !!**4:"r   c                     U R                   R                  [        U5      5      n[        R                  R                  XS U 5      $ r#   )rG   r   lenr   rf   _writeSomeData)r   datar   s      r   rk   ShapedConsumer._writeSomeData   s7    
 T+((777FmLLr   c                     [         R                  R                  U 5        U R                  =R                  S-  sl        g rS   )r   rf   stopProducingrG   r+   )r   s    r   ro   ShapedConsumer.stopProducing   s+    !!//5"r   )rG   N)
r$   r%   r&   r'   r(   iAmStreamingr   rk   ro   r,   r-   r   r   rc   rc      s     L#
M#r   rc   c                   "    \ rS rSrSrSrS rSrg)ShapedTransport   a:  
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}).
Fc                 .    [        U R                  U5      $ r#   )getattrrg   )r   names     r   __getattr__ShapedTransport.__getattr__   s     t}}d++r   r-   N)r$   r%   r&   r'   r(   rq   rx   r,   r-   r   r   rs   rs      s     L,r   rs   c                   $    \ rS rSrSrS rS rSrg)ShapedProtocolFactoryi  ao  
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}.
c                     Xl         X l        g)aT  
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}.
N)protocolbucketFilter)r   
protoClassr~   s      r   r   ShapedProtocolFactory.__init__  s     #(r   c                 `   ^ ^ T R                   " U0 UD6nUR                  mUU 4S jnXCl        U$ )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}.
c                 `   > TR                   R                  U 5      n[        X5      nT" U5      $ r#   )r~   r4   rs   )rW   rG   shapedTransportorigMakeConnectionr   s      r   makeConnection6ShapedProtocolFactory.__call__.<locals>.makeConnection,  s.    &&33I>F-i@O%o66r   )r}   r   )r   rD   rE   protor   r   s   `    @r   __call__ShapedProtocolFactory.__call__!  s6     q'B'"11	7
  .r   )r~   r}   N)r$   r%   r&   r'   r(   r   r   r,   r-   r   r   r{   r{     s    )"r   r{   N)r(   r   typingr   zope.interfacer   r   twisted.protocolsr   r	   r/   r7   rP   r\   rf   rc   rs   r{   r-   r   r   <module>r      s   
    1 !O! O!dI  ]@  @  @ F&+ &&- &#S.. #6,n ,(0 0r   