U
    d                     @  sx  U d Z ddlmZ ddlZddlZddlmZ ddlmZm	Z	 ddl
mZmZmZmZmZmZmZmZ ddlmZ eddd	Zd
ed< eddd	Zded< ededd	Zded< ddddZddddZddddZdddddZddddZdddd d!ZG d"d# d#Z ed$ed%ef d&Z!d$d$d'd(d)Z"d*d+dd,d-d.Z#d/Z$d0ed1< d2Z%d0ed3< G d4d5 d5Z&dS )6zInternal helpers for CSOT.    )annotationsN)deque)
ContextVarToken)AnyCallableDequeMutableMappingOptionalTupleTypeVarcast)WriteConcernTIMEOUT)defaultzContextVar[Optional[float]]RTT        zContextVar[float]DEADLINEinfOptional[float]returnc                   C  s
   t d S N)r   get r   r   1/tmp/pip-unpacked-wheel-oblwsawz/pymongo/_csot.pyget_timeout    s    r   floatc                   C  s   t  S r   )r   r   r   r   r   r   get_rtt$   s    r   c                   C  s   t  S r   )r   r   r   r   r   r   get_deadline(   s    r   None)rttr   c                 C  s   t |  d S r   )r   set)r!   r   r   r   set_rtt,   s    r#   c                   C  s   t  s
d S t t  S r   )r   r   r   time	monotonicr   r   r   r   	remaining0   s    r&   )max_timeoutr   c                 C  s   t  }|dkr| S t|| S )z4Return the remaining timeout clamped to a max value.N)r&   min)r'   timeoutr   r   r   clamp_remaining6   s    r*   c                   @  sD   e Zd ZdZdZddddZd ddd	Zd
d
d
ddddZdS )_TimeoutContextzInternal timeout context manager.

    Use :func:`pymongo.timeout` instead::

      with pymongo.timeout(0.5):
          client.test.test.insert_one({})
    _timeout_tokensr   )r)   c                 C  s   || _ d | _d S r   r,   )selfr)   r   r   r   __init__I   s    z_TimeoutContext.__init__r   c                 C  sZ   t | j}t }| jr(t | j ntd}tt||}t	d}|||f| _
| S )Nr   r   )r   r"   r-   r   r   r$   r%   r   r(   r   r.   )r/   timeout_tokenZprev_deadlineZnext_deadlinedeadline_token	rtt_tokenr   r   r   	__enter__M   s    
z_TimeoutContext.__enter__r   r    )exc_typeexc_valexc_tbr   c                 C  s4   | j r0| j \}}}t| t| t| d S r   )r.   r   resetr   r   )r/   r5   r6   r7   r1   r2   r3   r   r   r   __exit__V   s
    

z_TimeoutContext.__exit__N)__name__
__module____qualname____doc__	__slots__r0   r4   r9   r   r   r   r   r+   >   s
   	r+   F.)bound)funcr   c                   s,   t  ddddd fdd}tt|S )z/Apply the client's timeoutMS to this operation.r   r?   )r/   argskwargsr   c              
     sT   t  d krD| j}|d k	rDt|  | f||W  5 Q R  S Q R X  | f||S r   )r   r-   r+   )r/   rB   rC   r)   rA   r   r   csot_wrappere   s    

"zapply.<locals>.csot_wrapper)	functoolswrapsr   r?   )rA   rE   r   rD   r   applyb   s    rH   r	   zOptional[WriteConcern])cmdwrite_concernr   c                 C  s:   |r
|j rdS |j}t dk	r*|dd |r6|| d< dS )z+Apply the given write concern to a command.NZwtimeoutZwriteConcern)Zis_server_defaultdocumentr   pop)rI   rJ   Zwcr   r   r   apply_write_concernq   s    

rM   
   int_MAX_RTT_SAMPLES   _MIN_RTT_SAMPLESc                   @  sT   e Zd ZU dZded< ddddZddd	d
dZddddZddddZdS )MovingMinimumz4Tracks a minimum RTT within the last 10 RTT samples.zDeque[float]samplesr    r   c                 C  s   t td| _d S )N)maxlen)r   rP   rT   r/   r   r   r   r0      s    zMovingMinimum.__init__r   )sampler   c                 C  s   |dk rd S | j | d S )Nr   )rT   append)r/   rW   r   r   r   
add_sample   s    zMovingMinimum.add_samplec                 C  s   t | jtkrt| jS dS )z7Get the min, or 0.0 if there aren't enough samples yet.r   )lenrT   rR   r(   rV   r   r   r   r      s    
zMovingMinimum.getc                 C  s   | j   d S r   )rT   clearrV   r   r   r   r8      s    zMovingMinimum.resetN)	r:   r;   r<   r=   __annotations__r0   rY   r   r8   r   r   r   r   rS      s   
rS   )'r=   
__future__r   rF   r$   collectionsr   Zcontextvarsr   r   typingr   r   r   r	   r
   r   r   r   Zpymongo.write_concernr   r   r\   r   r   r   r   r   r   r#   r&   r*   r+   r?   rH   rM   rP   rR   rS   r   r   r   r   <module>   s.   (!