
    /Jf=                         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                     || _         || _        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 {} exceeded the amount available. Retry in {}N)requested_amt
retry_timeformatsuper__init__)selfr   r   msg	__class__s       W/home/alex/cs2snipeproduction/venv/lib/python3.11/site-packages/s3transfer/bandwidth.pyr
   z!RequestExceededException.__init__   sN     +$LSS:
 
 	    )__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.sleep6   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_streamN   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__f   s_    0  )%9"%({{D+/(*nn /r   c                     d| _         dS )z0Enable bandwidth limiting on reads to the streamTNr5   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.
        )r5   r3   readr7   r8   _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   )
r4   	exceptionr#   consumer7   r6   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/   )r3   seek)r   wherewhences      r   rK   zBandwidthLimitedStream.seek   s     5&)))))r   c                 4    | j                                         S r/   )r3   tellr   s    r   rO   zBandwidthLimitedStream.tell   s    }!!###r   c                 |    | j         r| j        r|                                  | j                                         d S r/   )r5   r7   r@   r3   closer   s    r   rQ   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/   )rQ   )r   argskwargss      r   __exit__zBandwidthLimitedStream.__exit__   s    

r   )Nr1   )r   )r   r   r   r
   r<   r)   r?   r@   rG   rI   rK   rO   rQ   rS   rW   r   r   r   r(   r(   e   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   rb   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   rD   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   rn   rp   projected_rates       r   rj   z)LeakyBucket._projected_to_exceed_max_rate  s'    +>>sHMM..r   c                 b    | j                             |           |                     ||          S r/   )rb   process_scheduled_consumptionrl   rm   s       r   ri   z8LeakyBucket._release_requested_amt_for_scheduled_request  s:     	#AA	
 	
 	
 **3999r   c                     |t          | j                  z  }| j                            |||          }t	          ||          )N)r   r   )r[   r\   rb   schedule_consumptionr   )r   rn   ro   rp   allocated_timer   s         r   rk   z-LeakyBucket._raise_request_exceeded_exception%  sS    uT^4440EE
 

 '*
 
 
 	
r   c                 <    | j                             ||           |S r/   )r`   record_consumption_rate)r   rn   rp   s      r   rl   z"LeakyBucket._release_requested_amt.  s     223AAA
r   )NNN)	r   r   r   r
   rD   rj   ri   rk   rl   r   r   r   rY   rY      s         "!A !A !A !AFB B B>/ / /: : :
 
 
    r   rY   c                   &    e Zd Zd Zd Zd Zd ZdS )rc   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__4  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   rh   z!ConsumptionScheduler.is_scheduled9  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   rn   r   r   s       r   rw   z)ConsumptionScheduler.schedule_consumptionB  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   ru   z2ConsumptionScheduler.process_scheduled_consumption\  sE     ?CCEJJ/@AA1
 
r   N)r   r   r   r
   rh   rw   ru   r   r   r   rc   rc   3  sP          
> > >     4

 

 

 

 

r   rc   c                   D    e Zd Zd	dZed             Zd Zd Zd Zd Z	dS )
ra   皙?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__j  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_ratez  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   rn   time_at_consumptions      r   rr   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   rz   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   r[   )r   rn   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   rn   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   rr   rz   r   r   r   r   r   ra   ra   i  s        " " " "  " " X"
 
 
$. . .$" " "O O O O Or   ra   )r]   r   	Exceptionr   r   r   r!   r(   rY   rc   ra   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   