
    `i                          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n# e$ r Y nw xY w ej        e          Zd Zdde
e         fdZ G d d          ZdS )	    N)OptionalTextIOUnionc                     t          j        ddt           j        t           j                  } | D ]}|\  }}}}}	 t          j         |||          }|                    d           |                    d           |c S # t          $ r0}|                                 t          d|            Y d}~d}~ww xY wt          d          )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           /home/jaya/work/projects/VOICE-AGENT/VIET/agent-env/lib/python3.11/site-packages/torch/distributed/elastic/rendezvous/etcd_server.pyfind_free_portr      s    ( tF,<6CU  E  	: 	:$(!eQ	:fdE22AFF#$$$HHQKKKHHH 	: 	: 	:GGIII8Q8899999999	: 2
3
33s   AA>>
B8&B33B8data_dirc                    | rG | j                     8t                              d            | j                      | j                     |r3t                              d|           t          j        |d           d S d S )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     ojo''/*+++

 40(;;;hd3333334 4    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dS )
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                            t
                    }t          j                            |d          }t          j                            d|          | _	        t          j        
                    | j	                  sd| _	        |r|nt          j        d          | _        d | _        d | _        d S )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    
 
wx((7<<j99!#+-="
 "
 w~~d455 	,%+D" !WHHh&6>V&W&W&W 	 6:r+   returnc                 <    | 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   
    z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                 $    | j          d| j         S )z,Return the etcd server endpoint (host:port).:)r5   r4   rJ   s    r   get_endpointzEtcdServer.get_endpoint   s    *++tz+++r+   <      timeoutnum_retriesstderrc                    d}	 	 t           j                            | j        t	          |                    }t          j        |d           |                     |||          S # t          $ rm}|dz  }t          | j	                   t                              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   rV   rW   rX   curr_retriesr   r   s          r   startzEtcdServer.start   s    , 	7<<(;S=N=NOOHt4444{{8Wf===   !$/***JCPQFF    ;..M$"5TJJJJ /....	s   AA$ $
C.A#CCc                 Z   t                      }t                      }|                                d         | _        |                                d         }t          j        d                    | j        dd|dd| j         d| j         dd| j         d| j         d	d| j         d| g
                    }t          	                    d
|           |
                                 |
                                 t          j        |d|          | _        |                     |           d S )Nr[    z--enable-v2z
--data-dirz--listen-client-urlszhttp://rR   z--advertise-client-urlsz--listen-peer-urlszStarting etcd server: [%s]T)	close_fdsrX   )r   getsocknamer4   shlexsplitr:   r=   r5   r#   r$   r   r)   PopenrC   _wait_for_ready)rD   r   rV   rX   sock	sock_peer	peer_portetcd_cmds           r   r^   zEtcdServer._start   s1    "$$	%%''*
))++A.	;HH*! *7dj774:77-7dj774:77(6dj66966 
 
" 	0(;;;

$*8tFSSSW%%%%%r+   c                 F    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     r|                                                                 +|                                 j        }t          d|           	 t          
                    d|j                   d S # t          $ r t	          j        d           Y nw xY wt	          j                    |k     t          d          )Nrr      rt   z*Etcd server process exited with the code: zetcd server ready. version: %sr[   z.Timed out waiting for etcd server to be ready!)r1   rw   r5   r4   timerK   r"   
returncoder   r#   r$   versionr_   sleepTimeoutError)rD   rV   clientmax_timeexitcodes        r   rl   zEtcdServer._wait_for_ready   s   Jtz%VW
 
 
 9;;(ikkH$$,,..3355A88::E"KKK  <fnMMM   
1 ikkH$$ KLLLs   # C C&%C&c                 n    t                               d           t          | j        | j                   dS )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   s0    3444$/4#677777r+   N)rT   rU   N)rT   N)rT   )rH   N)__name__
__module____qualname____doc__r   r\   rG   r)   rk   rK   intrM   rP   rS   r   r   rd   r^   rx   rl   r    r+   r   r-   r-   N   s        >; ;# ; ; ; ;$#**: # # # ##    #    ,c , , , , +/	%I %I%I %I c64'(	%I
 
%I %I %I %IP TX& &&&)&8=c64>O8P&	& & & &@
 
 
M Ms MD M M M M(8 8 8 8 8 8r+   r-   r   )ra   loggingr6   ri   r'   r   r)   r?   r{   typingr   r   r   r1   ModuleNotFoundError	getLoggerr   r#   r   r\   r*   r-   r   r+   r   <module>r      s-     				          * * * * * * * * * *	KKKK 	 	 	D	 
	8	$	$"4 "4 "4J4 4HSM 4 4 4 4j8 j8 j8 j8 j8 j8 j8 j8 j8 j8s   5 ==