
y X-/                 @   sx  d  d l  m Z d  d l m Z d  d l Z d  d l m 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 d d l m Z y d  d l j Z Wn e k
 re d   Yn Xy d  d l m Z Wn" e k
 rDd  d l m Z Yn XGd d   d e  Z Gd d   d e j  Z d S)    )deque)datetimeN)partial)RLock   )http)wsgi)util   )base)sixzd
    You need to install the 'futures' package to use this worker with this
    Python version.
    )	selectorsc               @   sR   e  Z d  Z d d   Z d d   Z d d   Z d d   Z d	 d
   Z e Z d S)TConnc             C   sJ   | |  _  | |  _ | |  _ | |  _ d  |  _ d  |  _ |  j j d  d  S)NF)cfgsockclientservertimeoutparsersetblocking)selfr   r   r   r    r   H/home/ubuntu/projects/ifolica/build/gunicorn/gunicorn/workers/gthread.py__init__/   s    						zTConn.__init__c             C   st   |  j  j d  |  j d  k rp |  j j rR t j |  j  d d |  j j |  _  n  t j	 |  j |  j   |  _ n  d  S)NTserver_side)
r   r   r   r   Zis_sslsslwrap_socketZssl_optionsr   ZRequestParser)r   r   r   r   init;   s    z
TConn.initc             C   s   t  j    |  j j |  _ d  S)N)timer   	keepaliver   )r   r   r   r   set_timeoutF   s    zTConn.set_timeoutc             C   s   t  j |  j  d  S)N)r	   closer   )r   r   r   r   r!   J   s    zTConn.closec             C   s   |  j  | j  k  S)N)r   )r   otherr   r   r   __lt__M   s    zTConn.__lt__N)	__name__
__module____qualname__r   r   r    r!   r#   Z__cmp__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   S)ThreadWorkerc                s   t  t |   j | |   |  j j |  _ |  j j |  j j |  _ d  |  _ d  |  _ d  |  _	 t
   |  _ t
   |  _ d |  _ d  S)Nr   )superr'   r   r   worker_connectionsthreadsmax_keepalivedtpoolpoller_lockr   futures_keepnr_conns)r   argskwargs)	__class__r   r   r   U   s    			zThreadWorker.__init__c             C   s=   | j  | j } | d k r9 | j r9 | j d d  n  d  S)Nr   z*No keepalived connections can be handled. z3Check the number of worker connections and threads.)r)   r*   r   warning)clsr   logr+   r   r   r   check_configa   s    	zThreadWorker.check_configc                sM   t  j d |  j j  |  _ t j   |  _ t   |  _	 t
 t |   j   d  S)NZmax_workers)r/   ZThreadPoolExecutorr   r*   r,   r   DefaultSelectorr-   r   r.   r(   r'   init_process)r   )r4   r   r   r:   i   s    zThreadWorker.init_processc             C   sG   d |  _  |  j j |   |  j j d  t j d  t j d  d  S)NFg?r   )	aliver   Z
worker_intr,   shutdownr   sleepsysexit)r   sigframer   r   r   handle_quito   s
    	zThreadWorker.handle_quitc             C   s-   | | _  |  j j |  | j |  j  d  S)N)connr/   appendZadd_done_callbackfinish_request)r   fsrC   r   r   r   _wrap_futurew   s    	zThreadWorker._wrap_futurec             C   s6   | j    |  j j |  j |  } |  j | |  d  S)N)r   r,   ZsubmithandlerG   )r   rC   rF   r   r   r   enqueue_req|   s    
zThreadWorker.enqueue_reqc             C   s   yJ | j    \ } } t |  j | | |  } |  j d 7_ |  j |  WnL t k
 r } z, | j t j t j t j	 f k r   n  WYd  d  } ~ Xn Xd  S)Nr
   )
acceptr   r   r1   rI   EnvironmentErrorerrnoEAGAINECONNABORTEDEWOULDBLOCK)r   r   Zlistenerr   r   rC   er   r   r   rJ      s    zThreadWorker.acceptc             C   s^   |  j  B |  j j |  y |  j j |  Wn t k
 rF d  SYn XWd  QX|  j |  d  S)N)r.   r-   
unregisterr0   remove
ValueErrorrI   )r   rC   r   r   r   r   reuse_connection   s    
zThreadWorker.reuse_connectionc          %   C   s  t  j    } x|  j . y |  j j   } Wn t k
 rA PYn XWd  QX| j | } | d k r |  j  |  j j |  Wd  QXPq |  j d 8_ |  j m y |  j j	 | j
  WnN t k
 r } z | j t j k r   n  WYd  d  } ~ Xn t k
 rYn XWd  QX| j   q Wd  S)Nr   r
   )r   r.   r0   popleft
IndexErrorr   
appendleftr1   r-   rQ   r   rK   rL   EBADFKeyErrorr!   )r   nowrC   deltarP   r   r   r   murder_keepalived   s,    


zThreadWorker.murder_keepalivedc             C   s0   |  j  t j   k r, |  j j d |   d Sd S)Nz!Parent changed, shutting down: %sFT)Zppidosgetppidr7   info)r   r   r   r   is_parent_alive   s    zThreadWorker.is_parent_alivec             C   s  xU |  j  D]J } | j d  | j   } t |  j |  } |  j j | t j |  q
 Wx |  j	 rE|  j
   |  j |  j k  r |  j j d  } x* | D]" \ } } | j } | | j  q Wt j |  j d d d t j } n! t j |  j d d d t j } x! | j D] }	 |  j j |	  qW|  j   s8Pn  |  j   q[ W|  j j d  |  j j   x |  j  D] }
 |
 j   qmWt j |  j d |  j j d  S)NFg      ?r   r   Zreturn_when)Zsocketsr   getsocknamer   rJ   r-   registerr   
EVENT_READr;   notifyr1   r)   selectdatafileobjr/   waitZFIRST_COMPLETEDdonerR   r`   r\   r,   r<   r!   r   Zgraceful_timeout)r   r   r   ZacceptoreventskeymaskcallbackresultZfutsr   r   r   run   s4    
	zThreadWorker.runc             C   s   | j    r | j j   d  Sy | j   \ } } | r | j j d  | j   |  j = |  j j	 |  |  j
 j | j t j t |  j |   Wd  QXn |  j d 8_ | j   Wn$ |  j d 8_ | j j   Yn Xd  S)NFr
   )Z	cancelledrC   r!   rn   r   r   r    r.   r0   rD   r-   rb   r   rc   r   rT   r1   )r   rF   r   rC   r   r   r   rE      s"    

zThreadWorker.finish_requestc             C   s&  d } d  } yH t  j | j  } | s1 d | f S|  j | |  } | rS | | f SWnt j j k
 r } z |  j j d |  WYd  d  } ~ Xnt	 k
 r } z |  j j d |  WYd  d  } ~ XnQt
 j k
 rT} zg | j d t
 j k r|  j j d  | j j   n, |  j j d  |  j | | j | j |  WYd  d  } ~ Xn t k
 r} zh | j t j t j f k r|  j j d  n5 | j t j k r|  j j d  n |  j j d	  WYd  d  } ~ XnA t k
 r} z! |  j | | j | j |  WYd  d  } ~ Xn Xd | 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 connection epipe)r   nextr   handle_requestr   errorsZ
NoMoreDatar7   debugStopIterationr   SSLErrorr2   SSL_ERROR_EOFr   r!   handle_errorr   rK   rL   EPIPE
ECONNRESET	exception	Exception)r   rC   r   reqrP   r   r   r   rH     s8    
%%."/zThreadWorker.handlec       	       C   s  i  } d  } zYy|  j  j |  |  t j   } t j | | j | j | j |  j   \ } } d | d <|  j	 d 7_	 |  j
 r |  j	 |  j k r |  j j d  | j   d |  _
 n  |  j  j s | j   n% t |  j  |  j k r | j   n  |  j | | j  } zx t | | d  r1| j |  n x | D] } | j |  q8W| j   t j   | } |  j j | | | |  Wd  t | d  r| j   n  X| j   r|  j j d  d SWn t k
 rt j t j      Yny t! k
 rc| r\| j" r\|  j j# d	  y$ | j j$ t% j&  | j j   Wn t k
 rOYn Xt'    n    Yn XWd  y |  j  j( |  | | |  Wn" t! k
 r|  j j# d
  Yn XXd S)NTzwsgi.multithreadr
   z,Autorestarting worker after current request.Fzwsgi.file_wrapperr!   zClosing connection.zError handling requestzException in post_request hook))r   Zpre_requestr   rZ   r   creater   r   r   nrr;   Zmax_requestsr7   r_   Zforce_closer   lenr0   r+   Zstart_response
isinstance
write_filewriter!   accesshasattrZshould_closert   rK   r   reraiser>   exc_infor|   Zheaders_sentr{   r<   socket	SHUT_RDWRru   Zpost_request)	r   r}   rC   environrespZrequest_startZrespiteritemZrequest_timer   r   r   rr   8  s`    


zThreadWorker.handle_request)r$   r%   r&   r   classmethodr8   r:   rB   rG   rI   rJ   rT   r\   r`   rp   rE   rH   rr   r   r   )r4   r   r'   S   s    0&r'   )collectionsr   r   rL   	functoolsr   r]   r   r   r>   	threadingr   r    r   r   r	   r   r   Zconcurrent.futuresr/   ImportErrorRuntimeErrorZasyncior   Zgunicornobjectr   ZWorkerr'   r   r   r   r   <module>   s2   &