U
    ª/ej%  ã                   @   sp  d dl Z d dlZd dlmZ d dlmZ d dlZd dlmZ d dlm	Z	mZ d dl
mZmZmZmZmZ d dlZd dlmZ d dlmZmZ d d	lmZmZ d d
lmZ d dlmZ d dl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% dZ&e 'e(¡Z)edd„ ƒZ*G dd„ dƒZ+d#dd„Z,dd„ Z-dd„ Z.ddl%m/Z/ ddl m!Z! G dd „ d e/ƒZ0G d!d"„ d"ƒZ1dS )$é    N)Úchain)Úbisect)Úadd)ÚsleepÚtime)Ú
accumulateÚtopkÚpluckÚmergeÚkeymap)Údefaultdict)ÚcontextmanagerÚsuppress)ÚThreadÚLock)Údatetime)ÚProcessé   )ÚDict)ÚFile)ÚBuffer)Úcores   -|-c               
   c   s>   z
d V  W n. t k
r8 }  zt | ¡ ‚ W 5 d } ~ X Y nX d S ©N)Ú	ExceptionÚloggerÚ	exception)Úe© r   ú-/tmp/pip-unpacked-wheel-ziavv1t7/partd/zmq.pyÚ	logerrors   s
    

r   c                   @   sp   e Zd Zddd„Zdd„ Zdd	„ Zd
d„ Zdd„ Zddd„Zdd„ Z	dd„ Z
dd„ Zdd„ Zdd„ Zdd„ ZdS )ÚServerNTFc                 C   sâ   t  ¡ | _|d kr ttƒ tƒ ƒ}|| _| j t j¡| _|d krFt 	¡ }t
|tƒrX| ¡ }|d krn| j d¡}n$| j |¡ t| d¡d  d¡ƒ}d||f  ¡ | _d| _| jj ¡  tƒ | _tƒ | _|rÒ|  ¡  |rÞ|  ¡  d S )Nztcp://*ú:éÿÿÿÿú/ztcp://%s:%dÚcreated)ÚzmqÚContextÚcontextr   r   r   ÚpartdÚsocketZROUTERÚgethostnameÚ
isinstanceÚstrÚencodeZbind_to_random_portÚbindÚintÚsplitÚrstripÚaddressÚstatusÚlockÚacquirer   Ú_lockÚ_socket_lockÚstartÚblock)Úselfr(   r.   r8   r9   ÚhostnameÚportr   r   r   Ú__init__&   s,    

zServer.__init__c                 C   s:   | j dkr6d| _ t| jd| _| j ¡  t d| j¡ d S )NÚrun)ÚtargetzStart server at %s)r3   r   ÚlistenÚ_listen_threadr8   r   Údebugr2   ©r:   r   r   r   r8   F   s
    

zServer.startc                 C   s(   z| j  ¡  W n tk
r"   Y nX dS )z Block until all threads close N)rA   ÚjoinÚAttributeErrorrC   r   r   r   r9   M   s    zServer.blockc           
   
   C   s6  t ƒ $ t d| j¡ | jdkr(| j d¡s2q| j | j ¡ }W 5 Q R X |d |d |dd …   }}}t d||¡ |dkr¤t d	¡ |  	|¡ d| _q(q|d
kr|d d d… |dd d…  }}t
tt|ƒƒ}tt||ƒƒ}| jj|dd t dt|ƒ¡ |  	|¡ q|dkrL|\}}t|ƒ}| jj||dd |  	|¡ q|dkr–t
tt|ƒƒ}t d|¡ |  |¡}	|  ||	¡ | j	|dd q|dkrÚt
tt|ƒƒ}t d|¡ | jj|dd | j	|dd q|dkrð|  	|¡ q|dkr|  ¡  |  	|¡ qt d|¡ td| ƒ‚qW 5 Q R X d S )NzStart listening %sÚclosedéd   r   r   é   zServer receives %s %só   closeúServer closesó   appendF©r4   úServer appends %d keysó   isetó   getzget %s)Úflow_controló   deletez	delete %só   synó   dropzUnknown command: %szUnknown command: )r   r   rB   r2   r3   r)   Úpollr7   Úrecv_multipartÚackÚlistÚmapÚdeserialize_keyÚdictÚzipr(   ÚappendÚlenZisetÚgetÚsend_to_clientÚdeleteÚdropÚ
ValueError)
r:   Úpayloadr2   ÚcommandÚkeysÚvaluesÚdataÚkeyÚvalueÚresultr   r   r   r@   T   sX    
 








zServer.listenc              
   C   sJ   t ƒ : t|tƒs|g}| j | j |g| ¡ W 5 Q R X W 5 Q R X d S r   )r   r+   rW   r7   r)   Úsend_multipart)r:   r2   rj   r   r   r   r_      s
    
zServer.send_to_clientc              	   C   s,   t ƒ  t d¡ |  |d¡ W 5 Q R X d S )NzServer sends ackó   ack)r   r   rB   r_   )r:   r2   rP   r   r   r   rV   ”   s    
z
Server.ackc                 C   s$   | j j|dd t dt|ƒ¡ d S )NFrL   rM   )r(   r\   r   rB   r]   )r:   rg   r   r   r   r\   ™   s    zServer.appendc              	   C   s    t ƒ  | j ¡  W 5 Q R X d S r   )r   r(   ra   rC   r   r   r   ra      s    zServer.dropc              
   C   sP   t ƒ @ t d|¡ | j | jj|dd}W 5 Q R X |W  5 Q R £ S Q R X d S )NzServer gets keys: %sFrL   )r   r   rB   r6   r(   r^   )r:   re   rj   r   r   r   r^   ¡   s
    z
Server.getc              	   C   sp   t  d¡ d| _|  ¡  ttjjƒ | j 	d¡ W 5 Q R X ttjjƒ | j
 d¡ W 5 Q R X | jj ¡  d S )NrJ   rF   r   é   )r   rB   r3   r9   r   r%   ÚerrorÚZMQErrorr)   Úcloser'   Údestroyr(   r4   ÚreleaserC   r   r   r   rp   ¨   s    
zServer.closec                 C   s   |   ¡  | S r   )r8   rC   r   r   r   Ú	__enter__²   s    zServer.__enter__c                 G   s   |   ¡  | jj|Ž  d S r   )rp   r(   Ú__exit__©r:   Úargsr   r   r   rt   ¶   s    zServer.__exit__)NNTFN)T)Ú__name__Ú
__module__Ú__qualname__r=   r8   r9   r@   r_   rV   r\   ra   r^   rp   rs   rt   r   r   r   r   r    %   s     ÿ
 9

r    çš™™™™™¹?é † c                 C   sx   t tt| ƒd dƒ|  ¡ dd}t|  ¡ ƒ}t|tdttt	t
td|ƒƒƒ|| ƒƒƒ}dd„ |d|… D ƒ}|stt‚|S )z² Which keys to remove

    >>> lengths = {'a': 20, 'b': 10, 'c': 15, 'd': 15,
    ...            'e': 10, 'f': 25, 'g': 5}
    >>> keys_to_flush(lengths, 0.5)
    ['f', 'a']
    rH   r   ©rh   c                 S   s   g | ]\}}|‘qS r   r   )Ú.0ÚkÚvr   r   r   Ú
<listcomp>Ê   s     z!keys_to_flush.<locals>.<listcomp>N)r   Úmaxr]   ÚitemsÚsumrf   Úminr   rW   r   r   r	   ÚAssertionError)ÚlengthsÚfractionZmaxcountÚtopÚtotalÚcutoffrj   r   r   r   Úkeys_to_flush»   s    þÿÿr‹   c                 C   sF   t | tƒrt tt| ƒ¡S t | tƒr(| S t | tƒr:|  ¡ S t| ƒ ¡ S )z`

    >>> serialize_key('x')
    b'x'
    >>> serialize_key(('a', 'b', 1))
    b'a-|-b-|-1'
    )	r+   ÚtupleÚ	tuple_seprD   rX   Úserialize_keyÚbytesr,   r-   r|   r   r   r   rŽ   Ï   s    


rŽ   c                 C   s   t | krt|  t ¡ƒS | S dS )zj

    >>> deserialize_key(b'x')
    b'x'
    >>> deserialize_key(b'a-|-b-|-1')
    (b'a', b'b', b'1')
    N)r   rŒ   r0   )Útextr   r   r   rY   à   s    rY   )Ú	Interfacec                   @   s~   e Zd Zddd„Zdd„ Zdd„ Zdd
d„Zd dd„Zd!dd„Zd"dd„Z	dd„ Z
dd„ Zdd„ Zdd„ Zdd„ Zdd„ ZdS )#ÚClientNFc                 K   s^   || _ t ¡ | _| j tj¡| _t d|¡ | j |¡ | j	dg dd t
ƒ | _t | ¡ d S )NzClient connects to %srR   F)Úack_required)r2   r%   r&   r'   r)   ZDEALERr   rB   ÚconnectÚsendÚNotALockr4   r‘   r=   )r:   r2   Úcreate_serverÚkwargsr   r   r   r=   ó   s    
zClient.__init__c                 C   s
   d| j iS )Nr2   )r2   rC   r   r   r   Ú__getstate__ý   s    zClient.__getstate__c                 C   s   |   |d ¡ t d¡ d S )Nr2   z%Reconstruct client from pickled state)r=   r   rB   )r:   Ústater   r   r   Ú__setstate__   s    zClient.__setstate__Tc                 C   sR   |r| j  ¡ }|dgkst‚t d|¡ | j  |g| ¡ |rJ| j  ¡ }nd }|S )Nrl   zClient sends command: %s)r)   rU   r…   r   rB   rk   )r:   rd   rc   Úrecvr“   rV   rj   r   r   r   r•     s    
zClient.sendc                 C   s.   t  d| j|¡ ttt|ƒƒ}| jd|ddS )zP

        Lock argument is ignored.  Everything is sequential (I think)
        zClient gets %s %srO   T)rœ   )r   rB   r2   rW   rX   rŽ   r•   ©r:   re   r4   r   r   r   Ú_get  s    zClient._getc                 C   sH   t  d| jtt|ƒƒd ¡ tt|ƒ}tt 	| 
¡ ¡ƒ}|  d|¡ d S )NzClient appends %s %sú keysrK   )r   rB   r2   r,   r]   r   rŽ   rW   r   Úfrom_iterabler‚   r•   )r:   rg   r4   rc   r   r   r   r\     s    
zClient.appendc                 C   s:   t  d| jtt|ƒƒd ¡ ttt|ƒƒ}|  d|¡ d S )NzClient deletes %s %srŸ   rQ   )	r   rB   r2   r,   r]   rW   rX   rŽ   r•   r   r   r   r   Ú_delete  s    zClient._deletec                 C   s   |   dt|ƒ|g¡ d S )NrN   )r•   rŽ   )r:   rh   ri   r   r   r   Ú_iset$  s    zClient._isetc                 C   s   |   dg ¡ tdƒ d S )NrS   gš™™™™™©?)r•   r   rC   r   r   r   ra   '  s    zClient.dropc                 C   s   |   dg ¡ d S )NrI   )r•   rC   r   r   r   Úclose_server+  s    zClient.close_serverc              	   C   s€   t | dƒr4ttjjƒ |  ¡  W 5 Q R X | j ¡  ttjjƒ | j 	d¡ W 5 Q R X ttjjƒ | j
 d¡ W 5 Q R X d S )NÚserver_processr   )Úhasattrr   r%   rn   ro   r£   r¤   rD   r)   rp   r'   rq   rC   r   r   r   rp   .  s    

zClient.closec                 C   s   |   ¡  |  ¡  d S r   )ra   rp   )r:   Útyperi   Ú	tracebackr   r   r   rt   8  s    zClient.__exit__c                 C   s   |   ¡  d S r   )rp   rC   r   r   r   Ú__del__<  s    zClient.__del__)NF)FT)N)N)N)rw   rx   ry   r=   r™   r›   r•   rž   r\   r¡   r¢   ra   r£   rp   rt   r¨   r   r   r   r   r’   ò   s   



	


r’   c                   @   s,   e Zd Zdd„ Zdd„ Zdd„ Zdd„ Zd	S )
r–   c                 C   s   d S r   r   rC   r   r   r   r5   A  ó    zNotALock.acquirec                 C   s   d S r   r   rC   r   r   r   rr   B  r©   zNotALock.releasec                 C   s   | S r   r   rC   r   r   r   rs   D  s    zNotALock.__enter__c                 G   s   d S r   r   ru   r   r   r   rt   G  s    zNotALock.__exit__N)rw   rx   ry   r5   rr   rs   rt   r   r   r   r   r–   @  s   r–   )rz   r{   )2r%   ÚloggingÚ	itertoolsr   r   r)   Úoperatorr   r   r   Ztoolzr   r   r	   r
   r   ÚuuidÚcollectionsr   Ú
contextlibr   r   Ú	threadingr   r   r   Úmultiprocessingr   r§   ÚsysrZ   r   Úfiler   Úbufferr   Ú r   r   Ú	getLoggerrw   r   r   r    r‹   rŽ   rY   r‘   r’   r–   r   r   r   r   Ú<module>   s@   

 
N