U
    lgT                     @   s   d 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Zddl	m
Z
 ddlmZ ddlmZ ddlmZmZmZ eeZG d	d
 d
eZG dd deZG dd de
ZG dd deZG dd deZdS )zA
RPC client/server implementation based on named pipe transport.
    N)Thread   )SearpcClient)searpc_server)SearpcTransport)make_socket_closeonexecrecvallsendallc                   @   s   e Zd ZdS )NamedPipeExceptionN)__name__
__module____qualname__ r   r   g/opt/seafile-pro-server-build/seafile-server/seafile/lib/python3.8/site-packages/pysearpc/named_pipe.pyr
      s   r
   c                   @   s0   e Zd ZdZdd Zdd Zdd Zdd	 Zd
S )NamedPipeTransportaR  
    This transport uses named pipes on windows and unix domain socket
    on linux/mac.

    It's compatible with the c implementation of named pipe transport.
    in lib/searpc-named-pipe-transport.[ch] files.

    The protocol is:
    - request: <32b length header><json request>
    - response: <32b length header><json response>
    c                 C   s   || _ d | _d S N)socket_pathpipeselfr   r   r   r   __init__&   s    zNamedPipeTransport.__init__c                 C   s    t  t j| _| j| j d S r   )socketAF_UNIXr   connectr   r   r   r   r   r   *   s    zNamedPipeTransport.connectc                 C   s   | j r| j   d | _ d S r   )r   closer   r   r   r   stop.   s    
zNamedPipeTransport.stopc           	      C   sv   t ||d}|jdd}tdt|}t| j| t| j| t| jd}t	d|\}t| j|}|j
ddS )N)servicerequestutf-8encodingz=I   )jsondumpsencodestructpacklenr	   r   r   unpackdecode)	r   r   	fcall_strZbodyZ	body_utf8headerresp_headerZ	resp_sizerespr   r   r   send3   s    zNamedPipeTransport.sendN)r   r   r   __doc__r   r   r   r/   r   r   r   r   r      s
   r   c                   @   s6   e Zd ZdddZdd Zdd Zdd	 Zd
d ZdS )NamedPipeClient   c                 C   s"   || _ || _|| _t|| _d S r   )r   service_name	pool_sizequeueZQueue_pool)r   r   r3   r4   r   r   r   r   H   s    zNamedPipeClient.__init__c                 C   s   t | j}|  |S r   )r   r   r   r   	transportr   r   r   _create_transportN   s    
z!NamedPipeClient._create_transportc                 C   s*   z| j d}W n   |  }Y nX |S NF)r6   getr9   r7   r   r   r   _get_transportS   s
    zNamedPipeClient._get_transportc                 C   s6   z| j |d W n tjk
r0   |  Y nX d S r:   )r6   Zputr5   ZFullr   r7   r   r   r   _return_transportZ   s    z!NamedPipeClient._return_transportc                 C   s$   |   }|| j|}| | |S r   )r<   r/   r3   r=   )r   r+   r8   Zret_strr   r   r   call_remote_func_sync`   s    
z%NamedPipeClient.call_remote_func_syncN)r2   )r   r   r   r   r9   r<   r=   r>   r   r   r   r   r1   G   s
   
r1   c                   @   s8   e Zd ZdZdd Zdd Zdd Zdd	 Zd
d ZdS )NamedPipeServerz
    Searpc server based on named pipe transport. Note this server is
    very basic and is written for testing purpose only.
    c                 C   s*   || _ d | _t| jd| _| jd d S )N)targetT)r   r   r   accept_loopthread	setDaemonr   r   r   r   r   l   s    zNamedPipeServer.__init__c                 C   s   |    | j  d S r   )init_socketrB   startr   r   r   r   rE   r   s    zNamedPipeServer.startc                 C   s   d S r   r   r   r   r   r   r   v   s    zNamedPipeServer.stopc                 C   s   t j| jrDzt | j W n$ tk
rB   td| jY nX ttj	tj
d| _t| j | j| j | jd td| j d S )Nz(Failed to remove existing unix socket {}r   
   zServer now listening at %s)ospathexistsr   unlinkOSErrorr
   formatr   r   ZSOCK_STREAMr   r   ZbindZlistenloggerinfor   r   r   r   rD   y   s    

zNamedPipeServer.init_socketc                 C   s8   t d | j \}}t d t|}|  q
d S )NzWaiting for clientszNew pip client)rM   rN   r   ZacceptPipeHandlerThreadrE   )r   Zconnfd_tr   r   r   rA      s
    

zNamedPipeServer.accept_loopN)	r   r   r   r0   r   rE   r   rD   rA   r   r   r   r   r?   g   s   r?   c                   @   s   e Zd Zdd Zdd ZdS )rO   c                 C   s   t |  | d || _d S )NT)r   r   rC   r   )r   r   r   r   r   r      s    

zPipeHandlerThread.__init__c                 C   s   t | jd}td|\}t | j|}t|jdd}t|d |d }t	dt
|}t| j| t| j|jdd q d S )Nr"   Ir   r    r   r   )r   r   r&   r)   r#   loadsr*   r   Zcall_functionr'   r(   r	   r%   )r   Z
req_headerZreq_sizeZreqdatar.   r-   r   r   r   run   s    zPipeHandlerThread.runN)r   r   r   r   rU   r   r   r   r   rO      s   rO   )r0   r#   ZloggingrG   r   r&   Z	threadingr   r5   Zclientr   Zserverr   r8   r   Zutilsr   r   r	   Z	getLoggerr   rM   	Exceptionr
   r   r1   objectr?   rO   r   r   r   r   <module>   s"   
. *