U
    d                     @   s   d dl Z d dlZd dlZd dl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 eeeef dddZeee dd	d
Zee eeeef dddZeedddZeeeeef f ddddZG dd dZdS )    N)	timedelta)EventThread)AnyCallableDictOptionalTupleUnion)
config_strreturnc                 C   s   i }|   } | s|S | d}|D ]Z}|dd^}}|  }|sJtd|r\|d   }nd}|sttd| d|||< q"|S )	zExtracts key-value pairs from a rendezvous configuration string.

    Args:
        config_str:
            A string in format <key1>=<value1>,...,<keyN>=<valueN>.
    ,=   zZThe rendezvous configuration string must be in format <key1>=<value1>,...,<keyN>=<valueN>.r   Nz%The rendezvous configuration option 'z' must have a value specified.)stripsplit
ValueError)r   config
key_valueskvkeyvaluesvalue r   N/tmp/pip-unpacked-wheel-ua33x9lu/torch/distributed/elastic/rendezvous/utils.py_parse_rendezvous_config   s*    


r   )port_strr   c                 C   s   | rt d| rt| S dS )z3Tries to extract the port number from ``port_str``.z^[0-9]{1,5}$N)rematchint)r   r   r   r   _try_parse_port8   s    r    )endpointdefault_portr   c                 C   s   | dk	r|   } | sd|fS | d dkrD| d dkrD| fg ^}}n| dd^}}t|dkr|d dkr|d dkr|dd }t|dkrt|d }|dks|d	krtd
|  dn|}td|std|  d||fS )a5  Extracts the hostname and the port number from a rendezvous endpoint.

    Args:
        endpoint:
            A string in format <hostname>[:<port>].
        default_port:
            The port number to use if the endpoint does not include one.

    Returns:
        A tuple of hostname and port number.
    N	localhostr   []:r   i   z,The port number of the rendezvous endpoint 'z)' must be an integer between 0 and 65536.z^[\w\.:-]+$z)The hostname of the rendezvous endpoint 'zN' must be a dot-separated list of labels, an IPv4 address, or an IPv6 address.)r   rsplitlenr    r   r   r   )r!   r"   hostrestportr   r   r   parse_rendezvous_endpoint?   s*    $

r-   )r*   r   c                 C   s   | dkrdS zt | }W n tk
r2   d}Y nX |rB|jrBdS t }| |krVdS tj|dtjtjd}|D ]<}|d r|d | kr dS |rp|d d t	|krp dS qpdS )	a=  Indicates whether ``host`` matches the hostname of this machine.

    This function compares ``host`` to the hostname as well as to the IP
    addresses of this machine. Note that it may return a false negative if this
    machine has CNAME records beyond its FQDN or IP addresses assigned to
    secondary NICs.
    r#   TN)protoflags      r   F)
	ipaddress
ip_addressr   is_loopbacksocketgethostnamegetaddrinfoIPPROTO_TCPAI_CANONNAMEstr)r*   addrZ	this_hostZ	addr_listZ	addr_infor   r   r   _matches_machine_hostnamen   s.    

   r<   )secondsr   c                 C   s*   t | trtj|  } | dkr&t|  dS )zSuspends the current thread for ``seconds``.

    Args:
        seconds:
            Either the delay, in seconds, or a tuple of a lower and an upper
            bound within which a random delay will be picked.
    g{Gz?N)
isinstancetuplerandomuniformtimesleep)r=   r   r   r   _delay   s    

rD   c                   @   s   e Zd ZU dZG dd dZee ed< ee ed< ee	j
 ed< eed< eed eed	d
ddZeee dddZed	dddZd	dddZd	dddZed	dddZedd Zd	S )_PeriodicTimerzRepresents a timer that periodically runs a specified function.

    Args:
        interval:
            The interval, in seconds, between each run.
        function:
            The function to run.
    c                   @   sJ   e Zd ZU eed< ed ed< eedf ed< ee	ef ed< e
ed< dS )	z_PeriodicTimer._Contextinterval.Nfunction.argskwargs
stop_eventN)__name__
__module____qualname__float__annotations__r   r	   r   r   r:   r   r   r   r   r   _Context   s
   
rQ   _name_thread
_finalizer_ctxrG   N)rF   rH   rI   rJ   r   c                 O   sV   d | _ |  | _| | j_|| j_|p*d| j_|p6i | j_t | j_	d | _
d | _d S )Nr   )rR   rQ   rU   total_secondsrF   rH   rI   rJ   r   rK   rS   rT   )selfrF   rH   rI   rJ   r   r   r   __init__   s    

z_PeriodicTimer.__init__)r   c                 C   s   | j S )zGets the name of the timer.)rR   rW   r   r   r   name   s    z_PeriodicTimer.name)rZ   r   c                 C   s   | j rtd|| _dS )zSets the name of the timer.

        The specified name will be assigned to the background thread and serves
        for debugging and troubleshooting purposes.
        The timer has already started.N)rS   RuntimeErrorrR   )rW   rZ   r   r   r   set_name   s    z_PeriodicTimer.set_namec                 C   s\   | j rtdt| j| jpd| jfdd| _ t| | j| j | jj	| _
d| j
_| j   dS )zStart the timer.r[   ZPeriodicTimerT)targetrZ   rI   daemonFN)rS   r\   r   _runrR   rU   weakreffinalize_stop_threadrK   rT   atexitstartrY   r   r   r   re      s           z_PeriodicTimer.startc                 C   s   | j r|    dS )z'Stop the timer at the next opportunity.N)rT   rY   r   r   r   cancel   s    z_PeriodicTimer.cancelc                 C   s$   | j | js | j| j| j q d S N)rK   waitrF   rH   rI   rJ   )ctxr   r   r   r`      s    z_PeriodicTimer._runc                 C   s   |   |   d S rg   )setjoin)threadrK   r   r   r   rc     s    z_PeriodicTimer._stop_thread)rL   rM   rN   __doc__rQ   r   r:   rP   r   ra   rb   r   r   r   rX   propertyrZ   r]   re   rf   staticmethodr`   rc   r   r   r   r   rE      s*   
rE   )r2   r@   r   r5   rB   ra   datetimer   	threadingr   r   typingr   r   r   r   r	   r
   r:   r   r   r    r-   boolr<   rO   rD   rE   r   r   r   r   <module>   s    &/& 