
    sg                          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Zd dlZd dlZd dl	m
Z
mZmZ 	 d dlZ ej                  e      Zd Zdde
e   fdZ G d d      Zy# e$ r Y 1w xY w)	    N)OptionalTextIOUnionc                     t        j                  ddt         j                  t         j                        } | D ]G  }|\  }}}}}	 t        j                   |||      }|j	                  d       |j                  d       |c S  t        d      # t        $ r(}j                          t        d|        Y d}~d}~ww xY w)a  
    Find a free port and binds a temporary socket to it so that the port can be "reserved" until used.

    .. note:: the returned socket must be closed before using the port,
              otherwise a ``address already in use`` error will happen.
              The socket should be held and closed as close to the
              consumer of the port as possible since otherwise, there
              is a greater chance of race-condition where a different
              process may see the port as being free and take it.

    Returns: a socket binded to the reserved free port

    Usage::

    sock = find_free_port()
    port = sock.getsockname()[1]
    sock.close()
    use_port(port)
    	localhostN)hostportfamilytype)r   r   r   z Socket creation attempt failed: zFailed to create a socket)
socketgetaddrinfo	AF_UNSPECSOCK_STREAMbindlistenOSErrorcloseprintRuntimeError)addrsaddrr
   r   proto_ses           c/var/www/html/venv/lib/python3.12/site-packages/torch/distributed/elastic/rendezvous/etcd_server.pyfind_free_portr      s    ( tF,<,<6CUCUE  	:$(!eQ	:fdE2AFF#$HHQKH	: 2
33  	:GGI4QC899	:s   :B	B>B99B>data_dirc                     | rH | j                          7t        j                  d        | j                           | j                          |r.t        j                  d|       t        j                  |d       y y )Nzstopping etcd serverzdeleting etcd data dir: %sTignore_errors)pollloggerinfo	terminatewaitshutilrmtree)
subprocessr   s     r   	stop_etcdr*   C   s_    ojoo'/*+

0(;hd3     c            
           e Zd ZdZddee   fdZdej                  fdZ	de
fdZdefdZdefd	Z	 	 	 dd
e
de
dee
edf   ddfdZ	 dded
e
dee
edf   ddfdZd Zdd
e
ddfdZddZy)
EtcdServera  
    .. note:: tested on etcd server v3.4.3.

    Starts and stops a local standalone etcd server on a random free
    port. Useful for single node, multi-worker launches or testing,
    where a sidecar etcd server is more convenient than having to
    separately setup an etcd server.

    This class registers a termination handler to shutdown the etcd
    subprocess on exit. This termination handler is NOT a substitute for
    calling the ``stop()`` method.

    The following fallback mechanism is used to find the etcd binary:

    1. Uses env var TORCHELASTIC_ETCD_BINARY_PATH
    2. Uses ``<this file root>/bin/etcd`` if one exists
    3. Uses ``etcd`` from ``PATH``

    Usage
    ::

     server = EtcdServer("/usr/bin/etcd", 2379, "/tmp/default.etcd")
     server.start()
     client = server.get_client()
     # use client
     server.stop()

    Args:
        etcd_binary_path: path of etcd server binary (see above for fallback path)
    Nr   c                    d| _         d| _        t        j                  j	                  t
              }t        j                  j                  |d      }t        j                  j                  d|      | _	        t        j                  j                  | j                        sd| _	        |r|nt        j                  d      | _        d | _        d | _        y )Nr   zbin/etcdTORCHELASTIC_ETCD_BINARY_PATHetcdtorchelastic_etcd_data)prefix)_port_hostospathdirname__file__joinenvironget_etcd_binary_pathisfiletempfilemkdtemp_base_data_dir	_etcd_cmd
_etcd_proc)selfr   rootdefault_etcd_bins       r   __init__zEtcdServer.__init__n   s    
 
wwx(77<<j9!#+-="
 ww~~d445%+D" !Hh&6&6>V&W 	 6:r+   returnc                 H    | j                   st        d      | j                   S )Nz>No etcd server process started. Call etcd_server.start() first)rC   r   rD   s    r   _get_etcd_server_processz#EtcdServer._get_etcd_server_process   s%    P  ??"r+   c                     | j                   S )z)Return the port the server is running on.)r4   rJ   s    r   get_portzEtcdServer.get_port       zzr+   c                     | j                   S )z)Return the host the server is running on.)r5   rJ   s    r   get_hostzEtcdServer.get_host   rN   r+   c                 8    | j                    d| j                   S )z,Return the etcd server endpoint (host:port).:)r5   r4   rJ   s    r   get_endpointzEtcdServer.get_endpoint   s    **Qtzzl++r+   timeoutnum_retriesstderrc                    d}	 	 t         j                  j                  | j                  t	        |            }t        j
                  |d       | j                  |||      S # t        $ rj}|dz  }t        | j                         t        j                  dt	        |             ||k\  r"t        j                  | j                  d        Y d}~nd}~ww xY w)a  
        Start the server, and waits for it to be ready. When this function returns the sever is ready to take requests.

        Args:
            timeout: time (in seconds) to wait for the server to be ready
                before giving up.
            num_retries: number of retries to start the server. Each retry
                will wait for max ``timeout`` before considering it as failed.
            stderr: the standard error file handle. Valid values are
                `subprocess.PIPE`, `subprocess.DEVNULL`, an existing file
                descriptor (a positive integer), an existing file object, and
                `None`.

        Raises:
            TimeoutError: if the server is not ready within the specified timeout
        r   T)exist_ok   z4Failed to start etcd server, got error: %s, retryingr    N)r6   r7   r:   rA   strmakedirs_start	Exceptionr*   rC   r#   warningr'   r(   atexitregister)rD   rT   rU   rV   curr_retriesr   r   s          r   startzEtcdServer.start   s    , 77<<(;(;S=NOHt4{{8Wf== !$//*JCPQF  ;.MM$"5"5TJ / s   AA" "	C+A CCc                 B   t               }t               }|j                         d   | _        |j                         d   }t        j                  dj                  | j                  dd|dd| j                   d| j                   dd| j                   d| j                   d	d| j                   d| g
            }t        j                  d
|       |j                          |j                          t        j                  |d|      | _        | j                  |       y )NrY    z--enable-v2z
--data-dirz--listen-client-urlszhttp://rR   z--advertise-client-urlsz--listen-peer-urlszStarting etcd server: [%s]T)	close_fdsrV   )r   getsocknamer4   shlexsplitr:   r=   r5   r#   r$   r   r)   PopenrC   _wait_for_ready)rD   r   rT   rV   sock	sock_peer	peer_portetcd_cmds           r   r\   zEtcdServer._start   s    "$	%%'*
))+A.	;;HH**! *djj\4::,7-djj\4::,7(djj\9+6
" 	0(;

$**8tFSW%r+   c                 \    t        j                  | j                  | j                  dd      S )zNReturn an etcd client object that can be used to make requests to this server./v2
   r   r	   version_prefixread_timeout)r1   Clientr5   r4   rJ   s    r   
get_clientzEtcdServer.get_client   s%    {{$**UQS
 	
r+   c                    t        j                  | j                   | j                  dd      }t	        j                         |z   }t	        j                         |k  rh| j                         j                         (| j                         j                  }t        d|       	 t        j                  d|j                         y t        d      # t        $ r t	        j                  d       Y nw xY wt	        j                         |k  rH)Nrp      rr   z*Etcd server process exited with the code: zetcd server ready. version: %srY   z.Timed out waiting for etcd server to be ready!)r1   ru   r5   r4   timerK   r"   
returncoder   r#   r$   versionr]   sleepTimeoutError)rD   rT   clientmax_timeexitcodes        r   rj   zEtcdServer._wait_for_ready   s    JJ<tzz%VW
 99;(iikH$,,.335A88:EE"@
K <fnnM KLL  

1 iikH$s   $ C C10C1c                 n    t         j                  d       t        | j                  | j                         y)zGStop the server and cleans up auto generated resources (e.g. data dir).zEtcdServer stop method calledN)r#   r$   r*   rC   rA   rJ   s    r   stopzEtcdServer.stop   s#    34$//4#6#67r+   N)<      N)r   N)r   )rH   N)__name__
__module____qualname____doc__r   rZ   rG   r)   ri   rK   intrM   rP   rS   r   r   rb   r\   rv   rj   r    r+   r   r-   r-   N   s    >;# ;$#**:*: ## # ,c , +/	%I%I %I c64'(	%I
 
%IP TX&&&)&8=c64>O8P&	&@
Ms MD M(8r+   r-   r   )r_   loggingr6   rg   r'   r   r)   r?   ry   typingr   r   r   r1   ModuleNotFoundError	getLoggerr   r#   r   rZ   r*   r-   r   r+   r   <module>r      s{      	       * *	
 
		8	$"4J4HSM 4j8 j8o  		s   A A&%A&