î
&GäR¾2  ã               @   s9  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 m	 Z	 m
 Z
 m Z d Z d  Z d Z d Z d Z d Z d	 d
 d d d g Z d Z d Z d Z d Z d Z d Z d Z d Z Gd d „  d e ƒ Z Gd d „  d e ƒ Z Gd d „  d e ƒ Z Gd d „  d e ƒ Z  d S)é    N)Ú
basestringÚbytesÚstr)ÚPropertyÚgetErrorMsgÚUIDg      à?é   é   é   é   ÚclosedÚclosingZwaitingZhostingZ	connectedzClosed on command.zUnspecified problemz/Invalid stop reason specified (must be string).zConnection timed out.zHandshake timed out.zHandshake failed.z2Handshake failed (context cannot connect to self).zClosed from other end.c               @   s"   e  Z d  Z d Z d d „  Z d S)ÚConnectionCollectionz‹ ContextConnectionCollection()
    
    A list class that allows indexing using the name of the required
    Connection instance.
    
    c             C   so   t  | t ƒ r[ | s$ t d ƒ ‚ n  xD |  D] } | j | k r+ | Sq+ Wt d | ƒ ‚ n t j |  | ƒ Sd  S)Nz#An empty string is not a valid key.z!No connection know by the name %s)Ú
isinstancer   ÚKeyErrorÚnameÚlistÚ__getitem__)ÚselfÚkeyÚc© r   úK/Applications/pyzo2014a/lib/python3.4/site-packages/iep/yoton/connection.pyr   1   s    z ConnectionCollection.__getitem__N)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   r   r   r   r   r   )   s   r   c               @   sÀ  e  Z d  Z d Z d d d „ Z e d d „  ƒ Z e d d „  ƒ Z e d	 d
 „  ƒ Z e d d „  ƒ Z	 e d d „  ƒ Z
 e d d „  ƒ Z e d d „  ƒ Z e d d „  ƒ Z e d d „  ƒ Z e d d „  ƒ Z e d d „  ƒ Z e d d „  ƒ Z e d d „  ƒ Z e d d  „  ƒ Z e d! d" „  ƒ Z d# d$ d% „ Z d& d' d( „ Z d& d) d* „ Z d+ d, „  Z d- d. „  Z d/ d0 „  Z d1 d2 „  Z d3 d4 „  Z d5 d6 „  Z d7 d8 „  Z d9 d: „  Z  d& S);Ú
Connectionad   Connection(context, name='')
    
    Abstract base class for a connection between two Context objects.
    This base class defines the full interface; subclasses only need
    to implement a few private methods.
    
    The connection classes are intended as a simple interface for the 
    user, for example to query port number, and be notified of timeouts 
    and closing of the connection. 
    
    All connection instances are intended for one-time use. To make
    a new connection, instantiate a new Connection object. After
    instantiation, either _bind() or _connect() should be called.
    
    Ú c             C   s�   | |  _  | |  _ d |  _ d |  _ d |  _ d |  _ d |  _ d |  _ t |  _	 t
 j ƒ  |  _ t
 j ƒ  |  _ t j ƒ  |  _ |  j d ƒ d  S)Nr   r   )Ú_contextÚ_nameÚ
_hostname1Ú
_hostname2Ú_port1Ú_port2Ú_id2Ú_pid2ÚTIMEOUT_MINÚ_timeoutÚyotonÚSignalÚ_timedout_signalÚ_closed_signalÚ	threadingÚRLockÚ_lockÚ_set_status)r   Úcontextr   r   r   r   Ú__init__P   s    									zConnection.__init__c             C   s   |  j  S)zG Get the hostname corresponding to this end of the connection.
        )r!   )r   r   r   r   Ú	hostname1t   s    zConnection.hostname1c             C   s   |  j  S)zj Get the hostname for the other end of this connection.
        Is empty string if not connected.
        )r"   )r   r   r   r   Ú	hostname2{   s    zConnection.hostname2c             C   s   |  j  S)zŒ Get the port number corresponding to this end of the connection.
        When binding, use this port to connect the other context.
        )r#   )r   r   r   r   Úport1ƒ   s    zConnection.port1c             C   s   |  j  S)zf Get the port number for the other end of the connection.
        Is zero when not connected.
        )r$   )r   r   r   r   Úport2‹   s    zConnection.port2c             C   s
   |  j  j S)z? The id of the context on this side of the connection.
        )r   Z_id)r   r   r   r   Úid1“   s    zConnection.id1c             C   s   |  j  S)zD The id of the context on the other side of the connection.
        )r%   )r   r   r   r   Úid2š   s    zConnection.id2c             C   s
   t  j ƒ  S)z\ The pid of the context on this side of the connection.
        (hint: os.getpid())
        )ÚosÚgetpid)r   r   r   r   Úpid1¡   s    zConnection.pid1c             C   s   |  j  S)zE The pid of the context on the other side of the connection.
        )r&   )r   r   r   r   Úpid2©   s    zConnection.pid2c          
   C   s3   |  j  j ƒ  z |  j d k SWd |  j  j ƒ  Xd S)z‡ Get whether this connection instance is alive (i.e. either 
        waiting or connected, and not in the process of closing).
        r	   N)r/   ÚacquireÚ_statusÚrelease)r   r   r   r   Úis_alive°   s    zConnection.is_alivec          
   C   s3   |  j  j ƒ  z |  j d k SWd |  j  j ƒ  Xd S)z< Get whether this connection instance is connected.
        r
   N)r/   r=   r>   r?   )r   r   r   r   Úis_connected¼   s    zConnection.is_connectedc          
   C   s3   |  j  j ƒ  z |  j d k SWd |  j  j ƒ  Xd S)z­ Get whether this connection instance is waiting for a connection. 
        This is the state after using bind() and before another context 
        connects to it.
        r	   N)r/   r=   r>   r?   )r   r   r   r   Ú
is_waitingÇ   s    zConnection.is_waitingc             C   s   |  j  S)zÂ Signal emitted when the connection closes. The first argument
        is the ContextConnection instance, the second argument is the 
        reason for the disconnection (as a string).
        )r,   )r   r   r   r   r   Ô   s    zConnection.closedc              C   s   d d „  }  d d „  } t  ƒ  S)z‰ Set/get the amount of seconds that no data is received from
        the other side after which the timedout signal is emitted. 
        c             S   s   |  j  S)N)r(   )r   r   r   r   Úfgetâ   s    z Connection.timeout.<locals>.fgetc             S   sP   t  | t t f ƒ s$ t d ƒ ‚ n  | t k  rC t d t ƒ ‚ n  | |  _ d  S)Nztimeout must be a number.ztimeout must be at least %1.2f.)r   ÚintÚfloatÚ
ValueErrorr'   r(   )r   Úvaluer   r   r   Úfsetä   s
    z Connection.timeout.<locals>.fset)Úlocals)rC   rH   r   r   r   ÚtimeoutÝ   s    zConnection.timeoutc             C   s   |  j  S)aŸ   This signal is emitted when no data has been received for 
        over 'timeout' seconds. This can mean that the connection is unstable, 
        or that the other end is running extension code.
        
        Handlers are called with two arguments: the ContextConnection 
        instance, and a boolean. The latter is True when the connection
        times out, and False when data is received again.
        )r+   )r   r   r   r   Útimedoutí   s    
zConnection.timedoutc              C   s   d d „  }  d d „  } t  ƒ  S)ad   Set/get the name that this connection is known by. This name
        can be used to obtain the instance using the Context.connections 
        property. The name can be used in networks in which each context
        has a particular role, to easier distinguish between the different
        connections. Other than that, the name has no function.
        c             S   s   |  j  S)N)r    )r   r   r   r   rC     s    zConnection.name.<locals>.fgetc             S   s+   t  | t ƒ s t d ƒ ‚ n  | |  _ d  S)Nzname must be a string.)r   r   rF   r    )r   rG   r   r   r   rH     s    zConnection.name.<locals>.fset)rI   )rC   rH   r   r   r   r   ú   s    zConnection.nameg      @c             C   s   |  j  | ƒ S)z£ flush(timeout=3.0)
        
        Wait until all pending packages are send. An error
        is raised when the timeout passes while doing so.
        
        )Ú_flush)r   rJ   r   r   r   Úflush  s    zConnection.flushNc             C   s>   | d k r t  } n  |  j t t g k r. d S|  j | d ƒ S)aJ   close(reason=None)
        
        Close the connection, disconnecting the two contexts and 
        stopping all trafic. If the connection was waiting for a 
        connection, it stops waiting.
        
        Optionally, a reason for closing can be specified. A closed
        connection cannot be reused.
        
        NT)ÚSTOP_DEFAULT_REASONr>   ÚSTATUS_CLOSEDÚSTATUS_CLOSINGÚ_general_close_method)r   Úreasonr   r   r   Úclose  s
    	zConnection.closec             C   sX   | d k r t  } n  |  j t k r( d S|  j t k rH |  j t ƒ d S|  j | d ƒ S)aÍ   close_on_problem(reason=None)
        
        Disconnect the connection, stopping all trafic. If it was
        waiting for a connection, we stop waiting.
        
        Optionally, a reason for stopping can be specified. This is highly
        recommended in case the connection is closed due to a problem.
        
        In contrast to the normal close() method, this method does not
        try to notify the other end of the closing.
        
        NF)ÚSTOP_UNSPECIFIED_PROBLEMr>   rO   rP   r0   rQ   )r   rR   r   r   r   Úclose_on_problem0  s    	zConnection.close_on_problemc             C   s›   |  j  } |  j t ƒ t | t ƒ s. t } n  | rJ |  j rJ |  j ƒ  n  |  j t ƒ |  j	 j
 |  | ƒ |  j j r— t | } t d | | f ƒ n  d S)zJ general close method used by both close() and close_on_problem()
        zYoton: %s connection closed: %sN)r>   r0   rP   r   r   ÚSTOP_INVALID_REASONrA   Ú_notify_other_end_of_closingrO   r   Úemitr   Ú_verboseÚ	STATUSMAPÚprint)r   rR   Zsend_stop_messageZ
old_statusÚtmpr   r   r   rQ   R  s    		
z Connection._general_close_methodc             C   s   t  ƒ  ‚ d  S)N)ÚNotImplemented)r   ÚhostnameÚportZ	max_triesr   r   r   Ú_bindu  s    zConnection._bindc             C   s   t  ƒ  ‚ d  S)N)r]   )r   r^   r_   rJ   r   r   r   Ú_connectx  s    zConnection._connectc             C   s   t  ƒ  ‚ d  S)N)r]   )r   rJ   r   r   r   rL   {  s    zConnection._flushc             C   s   t  ƒ  ‚ d  S)N)r]   )r   r   r   r   rW   ~  s    z'Connection._notify_other_end_of_closingc             C   s   t  ƒ  ‚ d  S)N)r]   )r   Úpackager   r   r   Ú_send_package�  s    zConnection._send_packagec             C   s   t  ƒ  ‚ d  S)N)r]   )r   rb   r   r   r   Ú_inject_package„  s    zConnection._inject_packagec             C   sq   |  j  j ƒ  zO | |  _ | d k r[ |  j j r[ t | } t d | |  j |  j f ƒ n  Wd |  j  j	 ƒ  Xd S)zj Used to change the status. Subclasses can reimplement this 
        to get the desired behavior.
        r   zYoton: %s at %s:%s.N)
r/   r=   r>   r   rY   rZ   r[   r!   r#   r?   )r   ÚstatusÚactionr   r   r   r0   ‡  s    	
$zConnection._set_status)!r   r   r   r   r2   Úpropertyr3   r4   r5   r6   r7   r8   r;   r<   r@   rA   rB   r   r   rJ   rK   r   rM   rS   rU   rQ   r`   ra   rL   rW   rc   rd   r0   r   r   r   r   r   ?   s8   $	
"#r   c               @   s   e  Z d  Z d Z d S)ÚInterConnectiona   InterConnection(context, hostname, port, name='')
    
    Not implemented.
    
    Communication between two processes on the same machine can also
    be implemented via a memory mapped file or a pype. Would there
    be an advantage over the TcpConnection?
    
    
    N)r   r   r   r   r   r   r   r   rh   œ  s   
rh   c               @   s   e  Z d  Z d Z d S)ÚUDPConnectiona   UDPConnection(context, hostname, port, name='')
    
    Not implemented.
    
    Communication can also be done over UDP, but need protocol on top
    of UDP to make the connection robust. Is there a reason to implement
    this if we have Tcp?
    
    N)r   r   r   r   r   r   r   r   ri   «  s   	ri   )!r9   ÚsysÚtimer-   r)   Ú
yoton.miscr   r   r   r   r   r   r'   rO   rP   ZSTATUS_WAITINGZSTATUS_HOSTINGZSTATUS_CONNECTEDrZ   rN   rT   rV   ZSTOP_TIMEOUTZSTOP_HANDSHAKE_TIMEOUTZSTOP_HANDSHAKE_FAILEDZSTOP_HANDSHAKE_SELFZSTOP_CLOSED_FROM_THEREr   r   Úobjectr   rh   ri   r   r   r   r   Ú<module>   s4   ÿ ^