
    tni<                         d dl Z d dlZ G d de          Z G d d          Z G d d          Z G d d	          Z G d
 d          Z G d d          Z G d d          Z	 G d d          Z
dS )    Nc                        e Zd Z fdZ xZS )RequestExceededExceptionc                 v    || _         || _        d| d| }t                                          |           dS )a  Error when requested amount exceeds what is allowed

        The request that raised this error should be retried after waiting
        the time specified by ``retry_time``.

        :type requested_amt: int
        :param requested_amt: The originally requested byte amount

        :type retry_time: float
        :param retry_time: The length in time to wait to retry for the
            requested amount
        zRequest amount z) exceeded the amount available. Retry in N)requested_amt
retry_timesuper__init__)selfr   r   msg	__class__s       Q/var/www/html/gpu-tools/venv/lib/python3.11/site-packages/s3transfer/bandwidth.pyr	   z!RequestExceededException.__init__   sH     +$dddXbdd    )__name__
__module____qualname__r	   __classcell__)r   s   @r   r   r      s8                r   r   c                       e Zd ZdZdS )RequestTokenzDA token to pass as an identifier when consuming from the LeakyBucketN)r   r   r   __doc__ r   r   r   r   %   s        NNDr   r   c                       e Zd Zd Zd ZdS )	TimeUtilsc                 (    t          j                     S )zgGet the current time back

        :rtype: float
        :returns: The current time in seconds
        )timer
   s    r   r   zTimeUtils.time,   s     y{{r   c                 *    t          j        |          S )zwSleep for a designated time

        :type value: float
        :param value: The time to sleep for in seconds
        )r   sleep)r
   values     r   r   zTimeUtils.sleep4   s     z%   r   N)r   r   r   r   r   r   r   r   r   r   +   s2          ! ! ! ! !r   r   c                        e Zd ZddZ	 ddZdS )BandwidthLimiterNc                 P    || _         || _        |t                      | _        dS dS )a  Limits bandwidth for shared S3 transfers

        :type leaky_bucket: LeakyBucket
        :param leaky_bucket: The leaky bucket to use limit bandwidth

        :type time_utils: TimeUtils
        :param time_utils: Time utility to use for interacting with time.
        N)_leaky_bucket_time_utilsr   )r
   leaky_bucket
time_utilss      r   r	   zBandwidthLimiter.__init__>   s4     *%({{D r   Tc                 j    t          || j        || j                  }|s|                                 |S )a  Wraps a fileobj in a bandwidth limited stream wrapper

        :type fileobj: file-like obj
        :param fileobj: The file-like obj to wrap

        :type transfer_coordinator: s3transfer.futures.TransferCoordinator
        param transfer_coordinator: The coordinator for the general transfer
            that the wrapped stream is a part of

        :type enabled: boolean
        :param enabled: Whether bandwidth limiting should be enabled to start
        )BandwidthLimitedStreamr"   r#   disable_bandwidth_limiting)r
   fileobjtransfer_coordinatorenabledstreams        r   get_bandwith_limited_streamz,BandwidthLimiter.get_bandwith_limited_streamL   sD     (T')=t?O
 
  	0--///r   N)T)r   r   r   r	   r-   r   r   r   r    r    =   sA        + + + + 6:     r   r    c                   ^    e Zd Z	 	 ddZd Zd Zd Zd Zd Zd	 Z	ddZ
d Zd Zd Zd ZdS )r'   N   c                     || _         || _        || _        || _        |t	                      | _        d| _        t                      | _        d| _        || _	        dS )a[  Limits bandwidth for reads on a wrapped stream

        :type fileobj: file-like object
        :param fileobj: The file like object to wrap

        :type leaky_bucket: LeakyBucket
        :param leaky_bucket: The leaky bucket to use to throttle reads on
            the stream

        :type transfer_coordinator: s3transfer.futures.TransferCoordinator
        param transfer_coordinator: The coordinator for the general transfer
            that the wrapped stream is a part of

        :type time_utils: TimeUtils
        :param time_utils: The time utility to use for interacting with time
        NTr   )
_fileobjr"   _transfer_coordinatorr#   r   _bandwidth_limiting_enabledr   _request_token_bytes_seen_bytes_threshold)r
   r)   r$   r*   r%   bytes_thresholds         r   r	   zBandwidthLimitedStream.__init__d   s_    0  )%9"%({{D+/(*nn /r   c                     d| _         dS )z0Enable bandwidth limiting on reads to the streamTNr4   r   s    r   enable_bandwidth_limitingz0BandwidthLimitedStream.enable_bandwidth_limiting   s    +/(((r   c                     d| _         dS )z1Disable bandwidth limiting on reads to the streamFNr:   r   s    r   r(   z1BandwidthLimitedStream.disable_bandwidth_limiting   s    +0(((r   c                    | j         s| j                            |          S | xj        |z  c_        | j        | j        k     r| j                            |          S |                                  | j                            |          S )zhRead a specified amount

        Reads will only be throttled if bandwidth limiting is enabled.
        )r4   r2   readr6   r7   _consume_through_leaky_bucket)r
   amounts     r   r>   zBandwidthLimitedStream.read   s    
 / 	.=%%f--- 	F"d333=%%f---**,,,}!!&)))r   c                    | j         j        sq	 | j                            | j        | j                   d| _        d S # t          $ r)}| j                            |j	                   Y d }~nd }~ww xY w| j         j        q| j         j        )Nr   )
r3   	exceptionr"   consumer6   r5   r   r#   r   r   )r
   es     r   r?   z4BandwidthLimitedStream._consume_through_leaky_bucket   s     ,6 
	75"**$d&9   $% + 5 5 5 &&q|444444445 ,6 
	7 ,66s   ,< 
A/A**A/c                 .    |                                   dS )z6Signal that data being read is being transferred to S3N)r;   r   s    r   signal_transferringz*BandwidthLimitedStream.signal_transferring   s    &&(((((r   c                 .    |                                   dS )z:Signal that data being read is not being transferred to S3N)r(   r   s    r   signal_not_transferringz.BandwidthLimitedStream.signal_not_transferring   s    '')))))r   r   c                 <    | j                             ||           d S r.   )r2   seek)r
   wherewhences      r   rJ   zBandwidthLimitedStream.seek   s     5&)))))r   c                 4    | j                                         S r.   )r2   tellr   s    r   rN   zBandwidthLimitedStream.tell   s    }!!###r   c                 |    | j         r| j        r|                                  | j                                         d S r.   )r4   r6   r?   r2   closer   s    r   rP   zBandwidthLimitedStream.close   sE    + 	10@ 	1 ..000r   c                     | S r.   r   r   s    r   	__enter__z BandwidthLimitedStream.__enter__   s    r   c                 .    |                                   d S r.   )rP   )r
   argskwargss      r   __exit__zBandwidthLimitedStream.__exit__   s    

r   )Nr0   )r   )r   r   r   r	   r;   r(   r>   r?   rF   rH   rJ   rN   rP   rR   rV   r   r   r   r'   r'   c   s         "!0 !0 !0 !0F0 0 01 1 1* * *(7 7 7$) ) )* * ** * * *$ $ $        r   r'   c                   :    e Zd Z	 	 	 ddZd Zd Zd Zd Zd ZdS )	LeakyBucketNc                 
   t          |          | _        || _        |t                      | _        t	          j                    | _        || _        |t                      | _        || _	        |t                      | _	        dS dS )a9  A leaky bucket abstraction to limit bandwidth consumption

        :type rate: int
        :type rate: The maximum rate to allow. This rate is in terms of
            bytes per second.

        :type time_utils: TimeUtils
        :param time_utils: The time utility to use for interacting with time

        :type rate_tracker: BandwidthRateTracker
        :param rate_tracker: Tracks bandwidth consumption

        :type consumption_scheduler: ConsumptionScheduler
        :param consumption_scheduler: Schedules consumption retries when
            necessary
        N)float	_max_rater#   r   	threadingLock_lock_rate_trackerBandwidthRateTracker_consumption_schedulerConsumptionScheduler)r
   max_rater%   rate_trackerconsumption_schedulers        r   r	   zLeakyBucket.__init__   s    . x%({{D^%%
)!5!7!7D&;# (*>*@*@D''' )(r   c                    | j         5  | j                                        }| j                            |          r#|                     |||          cddd           S |                     ||          r|                     |||           n"|                     ||          cddd           S 	 ddd           dS # 1 swxY w Y   dS )ac  Consume an a requested amount

        :type amt: int
        :param amt: The amount of bytes to request to consume

        :type request_token: RequestToken
        :param request_token: The token associated to the consumption
            request that is used to identify the request. So if a
            RequestExceededException is raised the token should be used
            in subsequent retry consume() request.

        :raises RequestExceededException: If the consumption amount would
            exceed the maximum allocated bandwidth

        :rtype: int
        :returns: The amount consumed
        N)	r^   r#   r   ra   is_scheduled,_release_requested_amt_for_scheduled_request_projected_to_exceed_max_rate!_raise_request_exceeded_exception_release_requested_amtr
   amtrequest_tokentime_nows       r   rC   zLeakyBucket.consume   s   $ Z 	B 	B',,..H*77FF 	BHH 	B 	B 	B 	B 	B 	B 	B 	B 33CBB B66    223AA	B 	B 	B 	B 	B 	B 	B 	B	B 	B 	B 	B 	B 	B 	B 	B 	B 	B 	B 	B 	B 	B 	B 	B 	B 	Bs   A
B=AB==CCc                 N    | j                             ||          }|| j        k    S r.   )r_   get_projected_rater[   )r
   rm   ro   projected_rates       r   ri   z)LeakyBucket._projected_to_exceed_max_rate  s'    +>>sHMM..r   c                 b    | j                             |           |                     ||          S r.   )ra   process_scheduled_consumptionrk   rl   s       r   rh   z8LeakyBucket._release_requested_amt_for_scheduled_request  s:     	#AA	
 	
 	
 **3999r   c                     |t          | j                  z  }| j                            |||          }t	          ||          )N)r   r   )rZ   r[   ra   schedule_consumptionr   )r
   rm   rn   ro   allocated_timer   s         r   rj   z-LeakyBucket._raise_request_exceeded_exception#  sS    uT^4440EE
 

 '*
 
 
 	
r   c                 <    | j                             ||           |S r.   )r_   record_consumption_rate)r
   rm   ro   s      r   rk   z"LeakyBucket._release_requested_amt,  s     223AAA
r   )NNN)	r   r   r   r	   rC   ri   rh   rj   rk   r   r   r   rX   rX      s         "!A !A !A !AFB B B>/ / /: : :
 
 
    r   rX   c                   &    e Zd Zd Zd Zd Zd ZdS )rb   c                 "    i | _         d| _        dS )z*Schedules when to consume a desired amountr   N) _tokens_to_scheduled_consumption_total_waitr   s    r   r	   zConsumptionScheduler.__init__2  s    02-r   c                     || j         v S )zIndicates if a consumption request has been scheduled

        :type token: RequestToken
        :param token: The token associated to the consumption
            request that is used to identify the request.
        )r|   )r
   tokens     r   rg   z!ConsumptionScheduler.is_scheduled7  s     ===r   c                 T    | xj         |z  c_         | j         |d| j        |<   | j         S )a  Schedules a wait time to be able to consume an amount

        :type amt: int
        :param amt: The amount of bytes scheduled to be consumed

        :type token: RequestToken
        :param token: The token associated to the consumption
            request that is used to identify the request.

        :type time_to_consume: float
        :param time_to_consume: The desired time it should take for that
            specific request amount to be consumed in regardless of previously
            scheduled consumption requests

        :rtype: float
        :returns: The amount of time to wait for the specific request before
            actually consuming the specified amount.
        )wait_durationtime_to_consume)r}   r|   )r
   rm   r   r   s       r   rv   z)ConsumptionScheduler.schedule_consumption@  s@    & 	O+!-.8
 8
-e4 r   c                     | j                             |          }t          | j        |d         z
  d          | _        dS )zProcesses a scheduled consumption request that has completed

        :type token: RequestToken
        :param token: The token associated to the consumption
            request that is used to identify the request.
        r   r   N)r|   popmaxr}   )r
   r   scheduled_retrys      r   rt   z2ConsumptionScheduler.process_scheduled_consumptionZ  sE     ?CCEJJ/@AA1
 
r   N)r   r   r   r	   rg   rv   rt   r   r   r   rb   rb   1  sP          
> > >     4

 

 

 

 

r   rb   c                   D    e Zd Zd	dZed             Zd Zd Zd Zd Z	dS )
r`   皙?c                 0    || _         d| _        d| _        dS )a  Tracks the rate of bandwidth consumption

        :type a: float
        :param a: The constant to use in calculating the exponentional moving
            average of the bandwidth rate. Specifically it is used in the
            following calculation:

            current_rate = alpha * new_rate + (1 - alpha) * current_rate

            This value of this constant should be between 0 and 1.
        N)_alpha
_last_time_current_rate)r
   alphas     r   r	   zBandwidthRateTracker.__init__h  s      !r   c                 "    | j         dS | j        S )zmThe current transfer rate

        :rtype: float
        :returns: The current tracked transfer rate
        N        )r   r   r   s    r   current_ratez!BandwidthRateTracker.current_ratex  s     ?"3!!r   c                 @    | j         dS |                     ||          S )aZ  Get the projected rate using a provided amount and time

        :type amt: int
        :param amt: The proposed amount to consume

        :type time_at_consumption: float
        :param time_at_consumption: The proposed time to consume at

        :rtype: float
        :returns: The consumption rate if that amt and time were consumed
        Nr   )r   *_calculate_exponential_moving_average_rater
   rm   time_at_consumptions      r   rq   z'BandwidthRateTracker.get_projected_rate  s/     ?"3>>$
 
 	
r   c                 x    | j         || _         d| _        dS |                     ||          | _        || _         dS )a  Record the consumption rate based off amount and time point

        :type amt: int
        :param amt: The amount that got consumed

        :type time_at_consumption: float
        :param time_at_consumption: The time at which the amount was consumed
        Nr   )r   r   r   r   s      r   ry   z,BandwidthRateTracker.record_consumption_rate  sK     ?"1DO!$DF!LL$
 
 .r   c                 J    || j         z
  }|dk    rt          d          S ||z  S )Nr   inf)r   rZ   )r
   rm   r   
time_deltas       r   _calculate_ratez$BandwidthRateTracker._calculate_rate  s0    (4?:
??
 <<j!!r   c                 h    |                      ||          }| j        |z  d| j        z
  | j        z  z   S )N   )r   r   r   )r
   rm   r   new_rates       r   r   z?BandwidthRateTracker._calculate_exponential_moving_average_rate  s:     ''-@AA{X%T[D<N(NNNr   N)r   )
r   r   r   r	   propertyr   rq   ry   r   r   r   r   r   r`   r`   g  s        " " " "  " " X"
 
 
$. . .$" " "O O O O Or   r`   )r\   r   	Exceptionr   r   r   r    r'   rX   rb   r`   r   r   r   <module>r      s           y   (	 	 	 	 	 	 	 	! ! ! ! ! ! ! !$# # # # # # # #Ln n n n n n n nbZ Z Z Z Z Z Z Zz3
 3
 3
 3
 3
 3
 3
 3
lNO NO NO NO NO NO NO NO NO NOr   