o
    ´ªRh=  ã                   @   s†   d dl Z d dlZG dd„ deƒZG dd„ dƒZG dd„ dƒZG dd	„ d	ƒZG d
d„ dƒZG dd„ dƒZG dd„ dƒZ	G dd„ dƒZ
dS )é    Nc                       s   e Zd Z‡ fdd„Z‡  ZS )ÚRequestExceededExceptionc                    s(   || _ || _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__© úV/home/air/sanwanet/backup_V2/venv/lib/python3.10/site-packages/s3transfer/bandwidth.pyr      s   ÿz!RequestExceededException.__init__)Ú__name__Ú
__module__Ú__qualname__r   Ú__classcell__r   r   r
   r   r      s    r   c                   @   s   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   r   '   s    r   c                   @   s   e Zd Zdd„ Zdd„ ZdS )Ú	TimeUtilsc                 C   s   t   ¡ S )zgGet the current time back

        :rtype: float
        :returns: The current time in seconds
        )Útime©r   r   r   r   r   .   s   zTimeUtils.timec                 C   s
   t  |¡S )zwSleep for a designated time

        :type value: float
        :param value: The time to sleep for in seconds
        )r   Úsleep)r   Úvaluer   r   r   r   6   s   
zTimeUtils.sleepN)r   r   r   r   r   r   r   r   r   r   -   s    r   c                   @   s"   e Zd Zddd„Z	ddd„ZdS )	ÚBandwidthLimiterNc                 C   s$   || _ || _|du r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_utilsr   r   r   r   @   s
   	ÿzBandwidthLimiter.__init__Tc                 C   s"   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Ústreamr   r   r   Úget_bandwith_limited_streamN   s   ÿz,BandwidthLimiter.get_bandwith_limited_stream©N)T)r   r   r   r   r$   r   r   r   r   r   ?   s    
ÿr   c                   @   st   e Zd Z		ddd„Zdd„ Zdd„ Zd	d
„ Zdd„ Zdd„ Zdd„ Z	ddd„Z
dd„ Zdd„ Zdd„ Zdd„ ZdS )r   Né   c                 C   sF   || _ || _|| _|| _|du r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_thresholdr   r   r   r   f   s   
zBandwidthLimitedStream.__init__c                 C   ó
   d| _ dS )z0Enable bandwidth limiting on reads to the streamTN©r)   r   r   r   r   Úenable_bandwidth_limiting‰   ó   
z0BandwidthLimitedStream.enable_bandwidth_limitingc                 C   r.   )z1Disable bandwidth limiting on reads to the streamFNr/   r   r   r   r   r      r1   z1BandwidthLimitedStream.disable_bandwidth_limitingc                 C   sL   | j s	| j |¡S |  j|7  _| j| jk r| j |¡S |  ¡  | j |¡S )zhRead a specified amount

        Reads will only be throttled if bandwidth limiting is enabled.
        )r)   r'   Úreadr+   r,   Ú_consume_through_leaky_bucket)r   Úamountr   r   r   r2   ‘   s   zBandwidthLimitedStream.readc              
   C   sj   | j js1z| j | j| j¡ d| _W d S  ty, } z| j |j	¡ W Y d }~nd }~ww | j jr| j j‚)Nr   )
r(   Ú	exceptionr   Úconsumer+   r*   r   r   r   r   )r   Úer   r   r   r3   ¥   s   ÿ€ÿù
z4BandwidthLimitedStream._consume_through_leaky_bucketc                 C   ó   |   ¡  dS )z6Signal that data being read is being transferred to S3N)r0   r   r   r   r   Úsignal_transferring·   ó   z*BandwidthLimitedStream.signal_transferringc                 C   r8   )z:Signal that data being read is not being transferred to S3N)r   r   r   r   r   Úsignal_not_transferring»   r:   z.BandwidthLimitedStream.signal_not_transferringr   c                 C   s   | j  ||¡ d S r%   )r'   Úseek)r   ÚwhereÚwhencer   r   r   r<   ¿   s   zBandwidthLimitedStream.seekc                 C   s
   | j  ¡ S r%   )r'   Útellr   r   r   r   r?   Â   s   
zBandwidthLimitedStream.tellc                 C   s"   | j r
| jr
|  ¡  | j ¡  d S r%   )r)   r+   r3   r'   Úcloser   r   r   r   r@   Å   s   zBandwidthLimitedStream.closec                 C   s   | S r%   r   r   r   r   r   Ú	__enter__Ï   s   z BandwidthLimitedStream.__enter__c                 O   s   |   ¡  d S r%   )r@   )r   ÚargsÚkwargsr   r   r   Ú__exit__Ò   s   zBandwidthLimitedStream.__exit__)Nr&   )r   )r   r   r   r   r0   r   r2   r3   r9   r;   r<   r?   r@   rA   rD   r   r   r   r   r   e   s    
ú#

r   c                   @   sD   e Zd Z			ddd„Zdd„ Zdd„ Zdd	„ Zd
d„ Zdd„ ZdS )ÚLeakyBucketNc                 C   s^   t |ƒ| _|| _|du rtƒ | _t ¡ | _|| _|du r tƒ | _|| _	|du r-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_schedulerr   r   r   r   ×   s   

ÿzLeakyBucket.__init__c                 C   s”   | j = | j ¡ }| j |¡r|  |||¡W  d  ƒ S |  ||¡r+|  |||¡ n|  ||¡W  d  ƒ S W d  ƒ dS 1 sCw   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)	rJ   r   r   rM   Ú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_nowr   r   r   r6   ú   s   
ÿýÿ
õ"ùzLeakyBucket.consumec                 C   s   | j  ||¡}|| jkS r%   )rK   Úget_projected_raterG   )r   rX   rZ   Úprojected_rater   r   r   rT     s   
z)LeakyBucket._projected_to_exceed_max_ratec                 C   s   | j  |¡ |  ||¡S r%   )rM   Úprocess_scheduled_consumptionrV   rW   r   r   r   rS     s   ÿz8LeakyBucket._release_requested_amt_for_scheduled_requestc                 C   s*   |t | jƒ }| j |||¡}t||d‚)N)r   r   )rF   rG   rM   Úschedule_consumptionr   )r   rX   rY   rZ   Úallocated_timer   r   r   r   rU   %  s   ÿÿz-LeakyBucket._raise_request_exceeded_exceptionc                 C   s   | j  ||¡ |S r%   )rK   Úrecord_consumption_rate)r   rX   rZ   r   r   r   rV   .  s   z"LeakyBucket._release_requested_amt)NNN)	r   r   r   r   r6   rT   rS   rU   rV   r   r   r   r   rE   Ö   s    
û#	rE   c                   @   s,   e Zd Zdd„ Zdd„ Zdd„ Zdd„ Zd	S )
rN   c                 C   s   i | _ d| _dS )z*Schedules when to consume a desired amountr   N)Ú _tokens_to_scheduled_consumptionÚ_total_waitr   r   r   r   r   4  s   
zConsumptionScheduler.__init__c                 C   s
   || j v S )zÙIndicates 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.
        )ra   )r   Útokenr   r   r   rR   9  s   
z!ConsumptionScheduler.is_scheduledc                 C   s&   |  j |7  _ | 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)rb   ra   )r   rX   rc   re   r   r   r   r^   B  s
   þz)ConsumptionScheduler.schedule_consumptionc                 C   s&   | j  |¡}t| j|d  dƒ| _dS )zàProcesses 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.
        re   r   N)ra   ÚpopÚmaxrb   )r   rc   Úscheduled_retryr   r   r   r]   \  s   
ÿz2ConsumptionScheduler.process_scheduled_consumptionN)r   r   r   r   rR   r^   r]   r   r   r   r   rN   3  s
    	rN   c                   @   sB   e Zd Zddd„Zedd„ ƒZdd„ Zdd	„ Zd
d„ Zdd„ Z	dS )rL   çš™™™™™é?c                 C   s   || _ 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   Úalphar   r   r   r   j  s   
zBandwidthRateTracker.__init__c                 C   s   | j du rdS | jS )zmThe current transfer rate

        :rtype: float
        :returns: The current tracked transfer rate
        Nç        )rk   rl   r   r   r   r   Úcurrent_ratez  s   
z!BandwidthRateTracker.current_ratec                 C   s   | j du r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
        Nrn   )rk   Ú*_calculate_exponential_moving_average_rate©r   rX   Útime_at_consumptionr   r   r   r[   …  s
   
ÿz'BandwidthRateTracker.get_projected_ratec                 C   s2   | j du r|| _ 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
        Nrn   )rk   rl   rp   rq   r   r   r   r`   —  s   
	ÿ
z,BandwidthRateTracker.record_consumption_ratec                 C   s"   || j  }|dkrtdƒS || S )Nr   Úinf)rk   rF   )r   rX   rr   Ú
time_deltar   r   r   Ú_calculate_rate©  s   
z$BandwidthRateTracker._calculate_ratec                 C   s&   |   ||¡}| j| d| j | j  S )Né   )ru   rj   rl   )r   rX   rr   Únew_rater   r   r   rp   ³  s   z?BandwidthRateTracker._calculate_exponential_moving_average_rateN)ri   )
r   r   r   r   Úpropertyro   r[   r`   ru   rp   r   r   r   r   rL   i  s    



rL   )rH   r   Ú	Exceptionr   r   r   r   r   rE   rN   rL   r   r   r   r   Ú<module>   s   &q]6