o
    Òó·i±  ã                   @   s8   d dl Z d dlmZ G dd„ deƒZG dd„ deƒZdS )é    N)ÚIBatchedTimerc                   @   s(   e Zd ZdZdd„ Zdd„ Zdd„ ZdS )	Ú_BatchedCallzÃ
    Wraps IDelayedCall-implementing objects, implementing only the API
    which txaio promised in the first place: .cancel

    Do not create these yourself; use _BatchedTimer.call_later()
    c                 C   s   || _ || _|| _d S ©N)Ú_timerÚ_indexÚ_call)ÚselfÚtimerÚindexZthe_call© r   úSC:\Users\psant\Downloads\PAF backend\school\venv\Lib\site-packages\txaio/_common.pyÚ__init__'   s   
z_BatchedCall.__init__c                 C   s   | j  | j| ¡ d | _ d S r   )r   Ú_remove_callr   ©r   r   r   r   Úcancel-   s   
z_BatchedCall.cancelc                 C   s   |   ¡ S r   )r   r   r   r   r   Ú__call__1   s   z_BatchedCall.__call__N)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   r   r   r   r   r   r   r      s
    r   c                   @   s4   e Zd ZdZ	ddd„Zdd„ Zdd„ Zd	d
„ ZdS )Ú_BatchedTimera=  
    Internal helper.

    Instances of this are returned from
    :meth:`txaio.make_batched_timer` and that is the only way they
    should be instantiated. You may depend on methods from the
    interface class only (:class:`txaio.IBatchedTimer`)

    **NOTE** that the times are in milliseconds in this class!
    Nc                 C   s>   |dkrt dƒ‚t|ƒ| _|| _|| _|| _tƒ | _|| _d S )Nç        z!bucket_milliseconds must be > 0.0)	Ú
ValueErrorÚfloatÚ_bucket_millisecondsÚ_chunk_sizeÚ_get_secondsÚ_create_delayed_callÚdictÚ_bucketsÚ_loop)r   Zbucket_millisecondsÚ
chunk_sizeZseconds_providerZdelayed_call_creatorÚloopr   r   r   r   A   s   

z_BatchedTimer.__init__c           
         s¤   |   ¡ }t|| ƒd }|t|| j ƒ8 }t| |‡ ‡‡fdd„ƒ}z| j| d  |¡ W |S  tyQ   |d | }|  td|ƒ| j	|¡}	|	|gf| j|< Y |S w )z#
        IBatchedTimer API
        iè  c                      s   ˆˆ i ˆ¤ŽS r   r   r   ©ÚargsÚfuncÚkwargsr   r   Ú<lambda>Z   s    z*_BatchedTimer.call_later.<locals>.<lambda>é   ç     @�@r   N)
r   Úintr   r   r   ÚappendÚKeyErrorr   ÚmaxÚ_notify_bucket)
r   Údelayr%   r$   r&   ÚnowÚ	real_timeÚcallÚdiffÚdelayed_callr   r#   r   Ú
call_laterR   s"   ôýôz_BatchedTimer.call_laterc                    s`   ˆj | \}}ˆj |= g ‰ ‡ ‡‡fdd„‰ˆjt tt|ƒƒˆj ¡ }ˆ|ˆjtd|ƒƒ dS )z�
        Internal helper. This 'does' the callbacks in a particular bucket.

        :param real_time: the bucket to do callbacks on
        c                    s¤   | d |… D ]}z|ƒ  W q t y$ } zˆ  |¡ W Y d }~qd }~ww | |d … } | r:ˆ |d ˆ| ||¡ d S tˆ ƒrPd}ˆ D ]	}|d |¡7 }qBt|ƒ‚d S )Nr)   z'Error(s) processing call_later bucket:
z{}
)Ú	Exceptionr+   r   ÚlenÚformatÚRuntimeError)Úcallsr!   Zchunk_delay_msr2   ÚeÚmsg©ÚerrorsÚnotify_one_chunkr   r   r   r?   u   s,   
€ÿû	üz6_BatchedTimer._notify_bucket.<locals>.notify_one_chunkr   N)r   r   ÚmathÚceilr   r7   r   r-   )r   r1   r4   r:   Zdelay_msr   r=   r   r.   k   s   ÿz_BatchedTimer._notify_bucketc                 C   sN   z	| j | \}}W n
 ty   Y dS w | |¡ |s%| j |= | ¡  dS dS )zº
        Internal helper. Removes a (possibly still pending) call from a
        bucket. It is *not* an error of the bucket is gone (e.g. the
        call has already happened).
        N)r   r,   Úremover   )r   r1   r2   r4   r:   r   r   r   r   •   s   þ
þz_BatchedTimer._remove_callr   )r   r   r   r   r   r5   r.   r   r   r   r   r   r   5   s    
ú*r   )r@   Ztxaio.interfacesr   Úobjectr   r   r   r   r   r   Ú<module>   s   