U
    dR…f*  ã                   @   sÆ   d Z ddlmZ ddlZddlZddlmZmZm	Z	m
Z
mZ ddlmZ ddlmZ d	Zeej ej e¡d
¡ƒZddddgZG dd„ deƒZG dd„ deeƒZG dd„ de
eƒZddlmZmZ dS )zŒ
Tracking support similar to twitter finagle-thrift.

Note: When using tracking, every client should have a corresponding
server processor.
é    )Úabsolute_importNé   )ÚTClientÚTApplicationExceptionÚTMessageTypeÚ
TProcessorÚTType)Úloadé   )ÚVersionMixinZ"__thriftpy_tracing_method_name__v2ztracking.thriftÚTTrackedClientÚTTrackedProcessorÚTrackerBaseÚConsoleTrackerc                   @   s   e Zd Zdd„ ZdS )ÚRequestInfoc                 C   s@   || _ || _|| _|| _|| _|| _|| _|| _|	| _|
| _	dS )aS  Used to store call info.

        :request_id: used to identity a request
        :api: api name
        :seq: sequence number
        :client: client name
        :server: server name
        :status: request status
        :start: start timestamp
        :end: end timestamp
        :annotation: application-level key-value data
        N)
Ú
request_idÚapiÚseqÚclientÚserverÚstatusÚstartÚendÚ
annotationÚmeta)Úselfr   r   r   r   r   r   r   r   r   r   © r   úG/tmp/pip-unpacked-wheel-jqs7l_7o/thriftpy2/contrib/tracking/__init__.pyÚ__init__   s    zRequestInfo.__init__N)Ú__name__Ú
__module__Ú__qualname__r   r   r   r   r   r      s   r   c                       sH   e Zd Z‡ fdd„Zdd„ Z‡ fdd„Z‡ fdd„Z‡ fd	d
„Z‡  ZS )r   c              
      sb   t t| ƒj||Ž |  ¡  || _z|  ¡  W n0 tk
r\ } z|jtjkrL‚ W 5 d }~X Y nX d S ©N)	Úsuperr   r   Úinit_version_mixinÚtrackerÚ_negotiationr   ÚtypeÚUNKNOWN_METHOD)r   Útracker_handlerÚargsÚkwargsÚe©Ú	__class__r   r   r   7   s    zTTrackedClient.__init__c                 C   sÎ   | j  ttj| j¡ t ¡ }tj	|_
| j |¡ | | j ¡ | j  ¡  | j j ¡  | j ¡ \}}}|tjkrŽtƒ }| | j¡ | j ¡  |‚n<t ¡ }| | j¡ | j ¡  |  tj¡ |j
rÊ|  |j
¡ d S r"   )Ú_oprotZwrite_message_beginÚtrack_methodr   ÚCALLZ_seqidÚtrack_thriftÚUpgradeArgsr   ÚCURRENTÚversionr%   Zinit_handshake_infoÚwriteZwrite_message_endZtransÚflushÚ_iprotÚread_message_beginZ	EXCEPTIONr   ÚreadÚread_message_endÚUpgradeReplyÚupgrade_versionÚVERSION_SUPPORT_REQUEST_HEADER)r   r*   r   Úmsg_typeÚseqidÚxÚresultr   r   r   r&   C   s*    ÿ



zTTrackedClient._negotiationc                    s\   |   tj¡r2t ¡ | _| j | j¡ | j | j	¡ t
t ¡ d ƒ| _tt| ƒj|f|Ž d S )Néè  )Úcheck_versionr   r>   r2   ÚRequestHeaderÚ_headerr%   Z
gen_headerr6   r/   ÚintÚtimeÚ
send_startr#   r   Ú_send)r   Ú_apir+   r-   r   r   rJ   \   s    
zTTrackedClient._sendc                    s<   |   tj¡r,t ¡ }| | j¡ | j |¡ t	t
| ƒ |¡S r"   )rD   r   ÚVERSION_SUPPORT_RESPONSE_HEADERr2   ÚResponseHeaderr:   r8   r%   Zhandle_response_headerr#   r   Ú_recv)r   rK   Úresponse_headerr-   r   r   rN   e   s
    zTTrackedClient._recvc           	         sØ   |   tj¡s$tt| ƒj|f|ž|ŽS d }d}zTz&tt| ƒj|f|ž|Ž}d}|W W ¢.S  tk
r| } z
|}‚ W 5 d }~X Y nX W 5 t| jj| jj	| j
j| j
j||| jtt ¡ d ƒ| j
j| jjd
}| j
 ||¡ X d S )NFrC   )
r   r   r   r   r   r   r   r   r   r   T)rD   r   r>   r#   r   Ú_reqr   rF   r   r   r%   r   r   rI   rG   rH   r   r   ÚrecordÚBaseException)	r   rK   r*   r+   Ú	exceptionr   Zheader_infoÚresr,   r-   r   r   rP   m   s0    
özTTrackedClient._req)	r   r    r!   r   r&   rJ   rN   rP   Ú__classcell__r   r   r-   r   r   6   s
   	c                       s@   e Zd Z‡ fdd„Z‡ fdd„Zdd„ Zdd„ Zd	d
„ Z‡  ZS )r   c                    s*   t t| ƒj||Ž |  ¡  || _d| _d S ©NF)r#   r   r   r$   r%   Úduring_handshake)r   r)   r*   r+   r-   r   r   r   ‹   s    zTTrackedProcessor.__init__c                    sZ   | j dkr|  |¡}n.t ¡ }| |¡ | j |¡ tt| ƒ 	|¡}| j
||f|žŽ  d S rV   )Zis_upgradedÚ_try_upgrader2   rE   r:   r%   Úhandler#   r   Z
process_inÚ_do_process)r   ÚiprotÚoprotrT   Zrequest_headerr-   r   r   Úprocess‘   s    

zTTrackedProcessor.processc                 C   s¦   |  ¡ \}}}|tjkrŠ|tkrŠd| _t ¡ }| |¡ | j 	|¡ |  
tj¡ t ¡ }|jrr|  
|j¡ | j|_d|_dd„ }| ¡  n|  ||¡\}}||||fS )NTFc                   S   s   d S r"   r   r   r   r   r   Úcall®   s    z,TTrackedProcessor._try_upgrade.<locals>.call)r9   r   r1   r0   rW   r2   r3   r:   r%   Zhandle_handshake_infor=   r   r>   r<   r5   r4   Úonewayr;   Ú_process_in)r   r[   r   r?   r@   r*   rB   r^   r   r   r   rX   œ   s     

zTTrackedProcessor._try_upgradec                    s–   ˆ ˆj jkr.| tj¡ | ¡  ttjƒd fS tˆj ˆ d ƒƒ ‰ˆ 	|¡ | ¡  tˆj ˆ d ƒƒ }‡fdd„t
ˆjƒD ƒ‰‡ ‡‡‡fdd„}||fS )NÚ_argsZ_resultc                    s   g | ]}ˆ j | d  ‘qS )r
   )Úthrift_spec©Ú.0Úk©r*   r   r   Ú
<listcomp>Ä   s   ÿz1TTrackedProcessor._process_in.<locals>.<listcomp>c                      s   t ˆjˆ ƒ‡fdd„ˆD ƒŽ S )Nc                 3   s   | ]}ˆ j | V  qd S r"   )Ú__dict__rc   rf   r   r   Ú	<genexpr>É   s     z>TTrackedProcessor._process_in.<locals>.call.<locals>.<genexpr>)ÚgetattrZ_handlerr   ©r   Zapi_argsr*   r   r   r   r^   Ç   s    
ÿz+TTrackedProcessor._process_in.<locals>.call)Z_serviceZthrift_servicesÚskipr   ZSTRUCTr;   r   r(   rj   r:   Úsortedrb   )r   r   r[   rB   r^   r   rk   r   r`   ·   s"    ÿÿ

ÿzTTrackedProcessor._process_inc           	   
   C   sª   t |tƒr|  ||||¡S z|ƒ |_W n0 tk
rV } z|  ||¡sF‚ W 5 d }~X Y nX |js¦|  tj	¡r–| j
rxd| _
nt ¡ }| j |¡ | |¡ |  ||||¡ d S rV   )Ú
isinstancer   Zsend_exceptionÚsuccessÚ	ExceptionZhandle_exceptionr_   rD   r   rL   rW   r2   rM   r%   Zgen_response_headerr6   Zsend_result)	r   r[   r\   r   r@   rB   r^   r,   rO   r   r   r   rZ   Î   s"    
ÿ
zTTrackedProcessor._do_process)	r   r    r!   r   r]   rX   r`   rZ   rU   r   r   r-   r   r   Š   s
   )r   r   )Ú__doc__Ú
__future__r   Úos.pathÚosrH   Zthriftr   r   r   r   r   Úparserr	   r%   r   r0   ÚpathÚjoinÚdirnameÚ__file__r2   Ú__all__Úobjectr   r   r   r   r   r   r   r   r   Ú<module>   s   ÿT\