U
    Jc                     @   s   d dl Z d dlmZmZ d dlmZmZmZ d dlZ	d dl
mZ d dl
mZmZmZmZmZ d dlmZ ddlmZmZmZ dd	lmZmZ dd
lmZ ddlmZ G dd deZeedddZ eeeef dddZ!dS )    N)	b64decode	b64encode)OptionalTuplecast)Client)EtcdAlreadyExistEtcdCompareFailedEtcdExceptionEtcdKeyNotFound
EtcdResult)Store   )RendezvousConnectionErrorRendezvousParametersRendezvousStateError)RendezvousBackendToken)	EtcdStore)parse_rendezvous_endpointc                   @   s   e Zd ZU dZdZeed< eed< eed< deee	e e	e dddd	Z
eed
ddZe	eeef  d
ddZdee	e e	eeeef  dddZeeeef dddZdS )EtcdRendezvousBackenda  Represents an etcd-based rendezvous backend.

    Args:
        client:
            The ``etcd.Client`` instance to use to communicate with etcd.
        run_id:
            The run id of the rendezvous.
        key_prefix:
            The path under which to store the rendezvous state in etcd.
        ttl:
            The TTL of the rendezvous state. If not specified, defaults to two hours.
    i   _client_key_ttlN)clientrun_id
key_prefixttlreturnc                 C   sL   |st d|| _|r&|d | | _n|| _|r@|dkr@|| _n| j| _d S )Nz&The run id must be a non-empty string./r   )
ValueErrorr   r   r   _DEFAULT_TTL)selfr   r   r   r    r#   `/tmp/pip-unpacked-wheel-gikjz4vx/torch/distributed/elastic/rendezvous/etcd_rendezvous_backend.py__init__0   s    zEtcdRendezvousBackend.__init__)r   c                 C   s   dS )See base class.zetcd-v2r#   r"   r#   r#   r$   nameF   s    zEtcdRendezvousBackend.namec              
   C   sf   z| j | j}W nH tk
r(   Y dS  ttjjfk
rZ } ztd|W 5 d}~X Y nX | 	|S )r&   NCThe connection to etcd has failed. See inner exception for details.)
r   readr   r   r
   urllib3
exceptionsTimeoutErrorr   _decode_state)r"   resultexcr#   r#   r$   	get_stateK   s    zEtcdRendezvousBackend.get_state)statetokenr   c           	   
      s   t | }i } fdd}|rHzt|}W n tk
rF   |  Y S X |rV||d< nd|d< z jj j| jf|}W nN tt	fk
r   d}Y n4 t
tjjfk
r } ztd|W 5 d}~X Y nX |dkr| S  |d	}|S )
r&   c                     s       } | d k	r| d}|S d S )NF)F)r1   )r/   tmpr'   r#   r$   r1   `   s
    z2EtcdRendezvousBackend.set_state.<locals>.get_stateZ	prevIndexFZ	prevExistNr)   T)T)r   decodeintr    r   writer   r   r   r	   r
   r+   r,   r-   r   r.   )	r"   r2   r3   base64_statekwargsr1   r/   r0   r4   r#   r'   r$   	set_stateX   s2    	
zEtcdRendezvousBackend.set_state)r/   r   c              
   C   sP   |j  }zt|}W n. tjk
rD } ztd|W 5 d }~X Y nX ||jfS )Nz=The state object is corrupt. See inner exception for details.)valueencoder   binasciiErrorr   ZmodifiedIndex)r"   r/   r8   r2   r0   r#   r#   r$   r.      s    
z#EtcdRendezvousBackend._decode_state)NN)N)__name__
__module____qualname____doc__r!   
EtcdClient__annotations__strr6   r   r%   propertyr(   r   bytesr   r1   boolr:   r   r.   r#   r#   r#   r$   r      s0   
    +r   )paramsr   c           	   
   C   s   t | jdd\}}tt| dd}|dkr4td| dd  }|dkr`|d	kr`td
| d}|r| d}|r||f}| d}zt	||||||ddW S  t
tjjfk
r } ztd|W 5 d }~X Y nX d S )NiK	  )default_portread_timeout<   r   z,The read timeout must be a positive integer.protocolhttphttpsz#The protocol must be HTTP or HTTPS.ssl_certssl_cert_keyca_certT)rK   rM   certrR   Zallow_reconnectr)   )r   Zendpointr   r6   Z
get_as_intr    getstriplowerrC   r
   r+   r,   r-   r   )	rI   hostportrK   rM   rP   rQ   rR   r0   r#   r#   r$   _create_etcd_client   s:    


	rY   c                 C   s*   t | }t|| jdd}t|d}||fS )a
  Creates a new :py:class:`EtcdRendezvousBackend` from the specified
    parameters.

    +--------------+-----------------------------------------------------------+
    | Parameter    | Description                                               |
    +==============+===========================================================+
    | read_timeout | The read timeout, in seconds, for etcd operations.        |
    |              | Defaults to 60 seconds.                                   |
    +--------------+-----------------------------------------------------------+
    | protocol     | The protocol to use to communicate with etcd. Valid       |
    |              | values are "http" and "https". Defaults to "http".        |
    +--------------+-----------------------------------------------------------+
    | ssl_cert     | The path to the SSL client certificate to use along with  |
    |              | HTTPS. Defaults to ``None``.                              |
    +--------------+-----------------------------------------------------------+
    | ssl_cert_key | The path to the private key of the SSL client certificate |
    |              | to use along with HTTPS. Defaults to ``None``.            |
    +--------------+-----------------------------------------------------------+
    | ca_cert      | The path to the rool SSL authority certificate. Defaults  |
    |              | to ``None``.                                              |
    +--------------+-----------------------------------------------------------+
    z/torch/elastic/rendezvous)r   z/torch/elastic/store)rY   r   r   r   )rI   r   backendstorer#   r#   r$   create_backend   s    
r\   )"r=   base64r   r   typingr   r   r   Zurllib3.exceptionsr+   Zetcdr   rC   r   r	   r
   r   r   Ztorch.distributedr   apir   r   r   Zdynamic_rendezvousr   r   Z
etcd_storer   utilsr   r   rY   r\   r#   r#   r#   r$   <module>   s   t)