U
    ÓB·f1  ã                   @   sÖ   d dl m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
 d dlmZ d dlmZ d dlmZ ddlmZ d	d
lmZ d	dlmZ d	dlmZ d	dlmZ G dd„ deƒZG dd„ dejƒZdS )é    )ÚfuturesN)Údeque)Údatetime)Úpartial)ÚRLocké   )Úbaseé   )Úhttp)Úutil)Úsock)Úwsgic                   @   s,   e Zd Zdd„ Zdd„ Zdd„ Zdd„ Zd	S )
ÚTConnc                 C   s:   || _ || _|| _|| _d | _d | _d| _| j d¡ d S )NF)Úcfgr   ÚclientÚserverÚtimeoutÚparserÚinitializedÚsetblocking)Úselfr   r   r   r   © r   ú</tmp/pip-unpacked-wheel-s8855r93/gunicorn/workers/gthread.pyÚ__init__$   s    zTConn.__init__c                 C   sP   d| _ | j d¡ | jd krL| jjr6t | j| j¡| _t | j| j| j	¡| _d S )NT)
r   r   r   r   r   Zis_sslÚssl_wrap_socketr
   ZRequestParserr   ©r   r   r   r   Úinit1   s    
z
TConn.initc                 C   s   t   ¡ | jj | _d S ©N)Útimer   Ú	keepaliver   r   r   r   r   Úset_timeout=   s    zTConn.set_timeoutc                 C   s   t  | j¡ d S r   )r   Úcloser   r   r   r   r   r!   A   s    zTConn.closeN)Ú__name__Ú
__module__Ú__qualname__r   r   r    r!   r   r   r   r   r   "   s   r   c                       s”   e Zd Z‡ fdd„Zedd„ ƒZ‡ fdd„Zdd„ Zd	d
„ Zdd„ Z	dd„ Z
dd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Z‡  ZS )ÚThreadWorkerc                    sV   t ƒ j||Ž | jj| _| jj| jj | _d | _d | _d | _t	ƒ | _
t	ƒ | _d| _d S )Nr   )Úsuperr   r   Úworker_connectionsÚthreadsÚmax_keepalivedÚtpoolÚpollerÚ_lockr   r   Ú_keepÚnr_conns)r   ÚargsÚkwargs©Ú	__class__r   r   r   G   s    
zThreadWorker.__init__c                 C   s(   |j |j }|dkr$|jr$| d¡ d S )Nr   z]No keepalived connections can be handled. Check the number of worker connections and threads.)r'   r(   r   Úwarning)Úclsr   Úlogr)   r   r   r   Úcheck_configS   s    zThreadWorker.check_configc                    s*   |   ¡ | _t ¡ | _tƒ | _tƒ  ¡  d S r   )	Úget_thread_poolr*   Ú	selectorsÚDefaultSelectorr+   r   r,   r&   Úinit_processr   r1   r   r   r:   [   s    

zThreadWorker.init_processc                 C   s   t j| jjdS )z@Override this method to customize how the thread pool is created)Úmax_workers)r   ZThreadPoolExecutorr   r(   r   r   r   r   r7   a   s    zThreadWorker.get_thread_poolc                 C   s6   d| _ | j | ¡ | j d¡ t d¡ t d¡ d S )NFgš™™™™™¹?r   )	Úaliver   Z
worker_intr*   Úshutdownr   ÚsleepÚsysÚexit)r   ÚsigÚframer   r   r   Úhandle_quite   s
    
zThreadWorker.handle_quitc                 C   s"   ||_ | j |¡ | | j¡ d S r   )Úconnr   ÚappendZadd_done_callbackÚfinish_request)r   ÚfsrD   r   r   r   Ú_wrap_futurem   s    zThreadWorker._wrap_futurec                 C   s(   |  ¡  | j | j|¡}|  ||¡ d S r   )r   r*   ZsubmitÚhandlerH   )r   rD   rG   r   r   r   Úenqueue_reqr   s    zThreadWorker.enqueue_reqc              
   C   sœ   z\|  ¡ \}}t| j|||ƒ}|  jd7  _| j" | j |jtj	t
| j|ƒ¡ W 5 Q R X W n: tk
r– } z|jtjtjtjfkr†‚ W 5 d }~X Y nX d S )Nr   )Úacceptr   r   r.   r,   r+   Úregisterr   r8   Ú
EVENT_READr   Úon_client_socket_readableÚEnvironmentErrorÚerrnoÚEAGAINÚECONNABORTEDÚEWOULDBLOCK)r   r   Zlistenerr   r   rD   Úer   r   r   rK   x   s    
ÿÿzThreadWorker.acceptc              	   C   sd   | j J | j |¡ |jrLz| j |¡ W n  tk
rJ   Y W 5 Q R £ d S X W 5 Q R X |  |¡ d S r   )r,   r+   Ú
unregisterr   r-   ÚremoveÚ
ValueErrorrJ   )r   rD   r   r   r   r   rN   ˆ   s    z&ThreadWorker.on_client_socket_readablec                 C   s  t   ¡ }| j: z| j ¡ }W n$ tk
rB   Y W 5 Q R £ qY nX W 5 Q R X |j| }|dkr„| j | j |¡ W 5 Q R X qq|  jd8  _| jp z| j 	|j
¡ W nV tk
rÜ } z|jtjkrÌ‚ W 5 d }~X Y n( tk
rî   Y n tk
r   Y nX W 5 Q R X | ¡  qd S )Nr   r   )r   r,   r-   ÚpopleftÚ
IndexErrorr   Ú
appendleftr.   r+   rU   r   rO   rP   ÚEBADFÚKeyErrorrW   r!   )r   ÚnowrD   ÚdeltarT   r   r   r   Úmurder_keepalived˜   s.     
zThreadWorker.murder_keepalivedc                 C   s$   | j t ¡ kr | j d| ¡ dS dS )Nz!Parent changed, shutting down: %sFT)ZppidÚosÚgetppidr5   Úinfor   r   r   r   Úis_parent_alive»   s    zThreadWorker.is_parent_alivec                 C   s  | j D ]4}| d¡ | ¡ }t| j|ƒ}| j |tj|¡ q| j	rÖ|  
¡  | j| jk r–| j d¡}|D ]\}}|j}||jƒ qftj| jdtjd}ntj| jdtjd}|jD ]}	| j |	¡ q°|  ¡ sÌqÖ|  ¡  q<| j d¡ | j ¡  | j D ]}
|
 ¡  qòtj| j| jjd d S )NFg      ð?r   )r   Zreturn_when)r   )Zsocketsr   Úgetsocknamer   rK   r+   rL   r8   rM   r<   Únotifyr.   r'   ÚselectÚdataÚfileobjr   ÚwaitZFIRST_COMPLETEDÚdonerV   rc   r_   r*   r=   r!   r   Zgraceful_timeout)r   r   r   ZacceptorÚeventsÚkeyÚ_ÚcallbackÚresultZfutÚsr   r   r   ÚrunÂ   s8    


ÿ
ÿ




zThreadWorker.runc              	   C   sÖ   |  ¡ r$|  jd8  _|j ¡  d S z€| ¡ \}}|rŒ| jrŒ|j d¡ | ¡  | j	. | j
 |¡ | j |jtjt| j|ƒ¡ W 5 Q R X n|  jd8  _| ¡  W n, tk
rÐ   |  jd8  _|j ¡  Y nX d S )Nr   F)Z	cancelledr.   rD   r!   ro   r<   r   r   r    r,   r-   rE   r+   rL   r8   rM   r   rN   Ú	Exception)r   rG   r   rD   r   r   r   rF   ò   s&    


ÿzThreadWorker.finish_requestc              
   C   sÞ  d}d }z8t |jƒ}|s"d|fW S |  ||¡}|r<||fW S W n” tjjk
rv } z| j d|¡ W 5 d }~X Y n` tk
r¦ } z| j d|¡ W 5 d }~X Y n0 t	j
k
r } zL|jd t	jkrâ| j d¡ |j ¡  n | j d¡ |  ||j|j|¡ W 5 d }~X Y nÄ tk
rž } zn|jtjtjtjfkrJ| j d¡ nD|jtjkrf| j d¡ n(|jtjkr‚| j d	¡ n| j d
¡ W 5 d }~X Y n8 tk
rÔ } z|  ||j|j|¡ W 5 d }~X Y nX d|fS )NFz*Ignored premature client disconnection. %szClosing connection. %sr   zssl connection closedzError processing SSL request.z Socket error processing request.zIgnoring connection resetzIgnoring socket not connectedzIgnoring connection epipe)Únextr   Úhandle_requestr
   ÚerrorsZ
NoMoreDatar5   ÚdebugÚStopIterationÚsslÚSSLErrorr/   ÚSSL_ERROR_EOFr   r!   Úhandle_errorr   rO   rP   ÚEPIPEÚ
ECONNRESETÚENOTCONNÚ	exceptionrr   )r   rD   r   ÚreqrT   r   r   r   rI     s<    

  $&zThreadWorker.handlec           	      C   s*  i }d }zÞzH| j  | |¡ t ¡ }t 	||j
|j|j| j ¡\}}d|d< |  jd7  _| j| jkr†| jr~| j d¡ d| _| ¡  | jr”| j jsž| ¡  nt| jƒ| jkr¶| ¡  |  ||j¡}z:t||d ƒrà| |¡ n|D ]}| |¡ qä| ¡  W 5 t ¡ | }| j ||||¡ t|dƒr2| ¡  X | ¡ rT| j d	¡ W W ¢šdS W nŽ tk
rz   t j!t" #¡ Ž  Y nl tk
rä   |rÞ|j$rÞ| j d
¡ z|j
 %t&j'¡ |j
 ¡  W n tk
rÖ   Y nX t(ƒ ‚‚ Y nX W 5 z| j  | |||¡ W n" tk
r"   | j d¡ Y nX X dS )NzException in post_request hookTzwsgi.multithreadr   z,Autorestarting worker after current request.Fr!   zwsgi.file_wrapperzClosing connection.zError handling request))r   Zpost_requestrr   r5   r   Zpre_requestr   r]   r   Úcreater   r   r   ÚnrZmax_requestsr<   rb   Zforce_closer   Úlenr-   r)   Zstart_responseÚaccessÚhasattrr!   Ú
isinstanceÚ
write_fileÚwriteZshould_closerv   rO   r   Úreraiser?   Úexc_infoZheaders_sentr=   ÚsocketÚ	SHUT_RDWRrw   )	r   r€   rD   ÚenvironÚrespZrequest_startZrespiterZrequest_timeÚitemr   r   r   rt   9  sf     ÿ


zThreadWorker.handle_request)r"   r#   r$   r   Úclassmethodr6   r:   r7   rC   rH   rJ   rK   rN   r_   rc   rq   rF   rI   rt   Ú__classcell__r   r   r1   r   r%   E   s    
#0(r%   )Z
concurrentr   rP   r`   r8   r‹   rx   r?   r   Úcollectionsr   r   Ú	functoolsr   Ú	threadingr   Ú r   r
   r   r   r   Úobjectr   ZWorkerr%   r   r   r   r   Ú<module>   s$   #