
mJ]c           @` s   d  Z  d d l m Z m Z m Z m Z d d l Z e j e  Z	 d d l
 Z
 d d l m Z m Z d d l m Z d d l m Z d Z d   Z d   Z d e f d     YZ d S(   u(    Provides the ``ServerSession`` class.

i    (   t   absolute_importt   divisiont   print_functiont   unicode_literalsN(   t   gent   locksi   (   t   yield_for_all_futuresi   (   t   _DocumentCallbackGroupu   current_timeu   ServerSessionc         ` s   t  j   f d    } | S(   u   Decorator that adds the necessary locking and post-processing
       to manipulate the session's document. Expects to decorate a
       method on ServerSession and transforms it into a coroutine
       if it wasn't already.
    c      	   ?` s   |  j  r( t j d  t j d    n  |  j   z |  j j   Vy |  j	 d  k	 rh t
 d d   n  g  |  _	 z t   |  | |   V} Wd  |  j	 } d  |  _	 Xx | D] } | Vq WWd  QXt j |   Wd  |  j   Xd  S(   Nu6   Ignoring locked callback on already-destroyed session.u3   internal class invariant violated: _pending_writes u"   should be None if lock is not held(   t	   destroyedt   logt   debugR   t   Returnt   Nonet   block_expirationt   _lockt   acquiret   _pending_writest   RuntimeErrorR   t   unblock_expiration(   t   selft   argst   kwargst   resultt   pending_writest   p(   t   func(    s3   lib/python2.7/site-packages/bokeh/server/session.pyt   _needs_document_lock_wrapper5   s$    	
		
(   R   t	   coroutine(   R   R   (    (   R   s3   lib/python2.7/site-packages/bokeh/server/session.pyt   _needs_document_lock/   s    c           C` s+   y t  j   d SWn t  j    d SXd S(   uW   Return the time in milliseconds since the epoch as a floating
       point number.
    i  N(   t   timet	   monotonic(    (    (    s3   lib/python2.7/site-packages/bokeh/server/session.pyt   current_timeX   s    t   ServerSessionc           B` s  e  Z d  Z d d  Z e d    Z e d    Z e d    Z e d    Z	 e d    Z
 e d    Z d   Z d	   Z d
   Z d   Z d   Z d   Z e d    Z e d    Z e d    Z d   Z d   Z d   Z d   Z e d    Z d   Z d   Z e d    Z e d    Z e d    Z  e d    Z! e d    Z" e d    Z# e d    Z$ RS(    u^    Hosts an application "instance" (an instantiated Document) for one or more connections.

    c         C` s   | d  k r t d   n  | d  k r6 t d   n  | |  _ | |  _ | |  _ t   |  _ t   |  _ t	 j
   |  _ d  |  _ |  j j |   t |  |  _ d  |  _ t |  _ t |  _ d |  _ |  j |  j j  } |  j j |  d  S(   Nu   Sessions must have an idu   Sessions must have a documenti    (   R   t
   ValueErrort   _idt	   _documentt   _loopt   sett   _subscribed_connectionsR   t   _last_unsubscribe_timeR   t   LockR   t   _current_patch_connectiont   on_change_dispatch_toR   t
   _callbacksR   t   Falset
   _destroyedt   _expiration_requestedt   _expiration_blocked_countt   _wrap_session_callbackst   session_callbackst   add_session_callbacks(   R   t
   session_idt   documentt   io_loopt   wrapped_callbacks(    (    s3   lib/python2.7/site-packages/bokeh/server/session.pyt   __init__h   s&    								c         C` s   |  j  S(   N(   R#   (   R   (    (    s3   lib/python2.7/site-packages/bokeh/server/session.pyR4   ~   s    c         C` s   |  j  S(   N(   R"   (   R   (    (    s3   lib/python2.7/site-packages/bokeh/server/session.pyt   id   s    c         C` s   |  j  S(   N(   R-   (   R   (    (    s3   lib/python2.7/site-packages/bokeh/server/session.pyR      s    c         C` s   |  j  S(   N(   R.   (   R   (    (    s3   lib/python2.7/site-packages/bokeh/server/session.pyt   expiration_requested   s    c         C` s   |  j  d k S(   Ni    (   R/   (   R   (    (    s3   lib/python2.7/site-packages/bokeh/server/session.pyt   expiration_blocked   s    c         C` s   |  j  S(   N(   R/   (   R   (    (    s3   lib/python2.7/site-packages/bokeh/server/session.pyt   expiration_blocked_count   s    c         C` s6   t  |  _ |  j j |   |  ` |  j j   |  ` d  S(   N(   t   TrueR-   R#   t   destroyR+   t   remove_all_callbacks(   R   (    (    s3   lib/python2.7/site-packages/bokeh/server/session.pyR=      s
    	c         C` s   t  |  _ d S(   uK    Used in test suite for now. Forces immediate expiration if no connections.N(   R<   R.   (   R   (    (    s3   lib/python2.7/site-packages/bokeh/server/session.pyt   request_expiration   s    c         C` s   |  j  d 7_  d  S(   Ni   (   R/   (   R   (    (    s3   lib/python2.7/site-packages/bokeh/server/session.pyR      s    c         C` s1   |  j  d k r t d   n  |  j  d 8_  d  S(   Ni    u0   mismatched block_expiration / unblock_expirationi   (   R/   R   (   R   (    (    s3   lib/python2.7/site-packages/bokeh/server/session.pyR      s    c         C` s   |  j  j |  d S(   ug   This should only be called by ``ServerConnection.subscribe_session`` or our book-keeping will be brokenN(   R&   t   add(   R   t
   connection(    (    s3   lib/python2.7/site-packages/bokeh/server/session.pyt	   subscribe   s    c         C` s    |  j  j |  t   |  _ d S(   ui   This should only be called by ``ServerConnection.unsubscribe_session`` or our book-keeping will be brokenN(   R&   t   discardR   R'   (   R   RA   (    (    s3   lib/python2.7/site-packages/bokeh/server/session.pyt   unsubscribe   s    c         C` s   t  |  j  S(   N(   t   lenR&   (   R   (    (    s3   lib/python2.7/site-packages/bokeh/server/session.pyt   connection_count   s    c         C` s   t    |  j S(   N(   R   R'   (   R   (    (    s3   lib/python2.7/site-packages/bokeh/server/session.pyt#   milliseconds_since_last_unsubscribe   s    c         O` s   | | |   S(   uH    Asynchronously locks the document and runs the function with it locked.(    (   R   R   R   R   (    (    s3   lib/python2.7/site-packages/bokeh/server/session.pyt   with_document_locked   s    c         ` s,   t    d t  r   S   f d   } | S(   Nu   nolockc          ` s    j    |  |  S(   N(   RH   (   R   R   (   t   callbackR   (    s3   lib/python2.7/site-packages/bokeh/server/session.pyt   wrapped_callback   s    (   t   getattrR,   (   R   RI   RJ   (    (   RI   R   s3   lib/python2.7/site-packages/bokeh/server/session.pyt   _wrap_document_callback   s    c         C` s   |  j  | j  } | j |  S(   N(   RL   RI   t   _copy_with_changed_callback(   R   RI   t   wrapped(    (    s3   lib/python2.7/site-packages/bokeh/server/session.pyt   _wrap_session_callback   s    c         C` s1   g  } x$ | D] } | j  |  j |   q W| S(   N(   t   appendRO   (   R   t	   callbacksRN   t   cb(    (    s3   lib/python2.7/site-packages/bokeh/server/session.pyR0      s    c         C` s   | j  |  k } |  j d  k r- t d   n  xR |  j D]G } | re | |  j k re t j d |  q7 |  j j | j	 |   q7 Wd  S(   Nuv   _pending_writes should be non-None when we have a document lock, and we should have the lock when the document changesuD   Not sending notification back to client %r for a change it requested(
   t   setterR   R   R   R&   R)   R	   t   traceRP   t   send_patch_document(   R   t   eventt   may_suppressRA   (    (    s3   lib/python2.7/site-packages/bokeh/server/session.pyt   _document_patched   s    c         C` s3   t  j d |  j  | j j d | j d |  j  S(   Nu&   Sending pull-doc-reply from session %ru   PULL-DOC-REPLYu   msgid(   R	   R
   R8   t   protocolt   createt   headerR4   (   R   t   messageRA   (    (    s3   lib/python2.7/site-packages/bokeh/server/session.pyt   _handle_pull   s    c         C` s&   |  j  | j  } |  j j |  d  S(   N(   RO   RI   R+   t   add_session_callback(   R   RV   RN   (    (    s3   lib/python2.7/site-packages/bokeh/server/session.pyt   _session_callback_added   s    c         C` s   |  j  j | j  d  S(   N(   R+   t   remove_session_callbackRI   (   R   RV   (    (    s3   lib/python2.7/site-packages/bokeh/server/session.pyt   _session_callback_removed   s    c         C` s   | j  j | |  S(   u?    Handle a PULL-DOC, return a Future with work to be scheduled. (   t   sessionR]   (   t   clsR\   RA   (    (    s3   lib/python2.7/site-packages/bokeh/server/session.pyt   pull   s    c         C` s0   t  j d |  j  | j |  j  | j |  S(   Nu   pushing doc to session %r(   R	   R
   R8   t   push_to_documentR4   t   ok(   R   R\   RA   (    (    s3   lib/python2.7/site-packages/bokeh/server/session.pyt   _handle_push   s    c         C` s   | j  j | |  S(   u?    Handle a PUSH-DOC, return a Future with work to be scheduled. (   Rb   Rg   (   Rc   R\   RA   (    (    s3   lib/python2.7/site-packages/bokeh/server/session.pyt   push   s    c         C` s:   | |  _  z | j |  j |   Wd  d  |  _  X| j |  S(   N(   R)   t   apply_to_documentR4   R   Rf   (   R   R\   RA   (    (    s3   lib/python2.7/site-packages/bokeh/server/session.pyt   _handle_patch   s
    	
c         C` s   | j  |  j  | j |  S(   N(   t   notify_eventR4   Rf   (   R   R\   RA   (    (    s3   lib/python2.7/site-packages/bokeh/server/session.pyt   _handle_event  s    c         C` s   | j  j | |  S(   N(   Rb   Rl   (   Rc   R\   RA   (    (    s3   lib/python2.7/site-packages/bokeh/server/session.pyRV     s    c         C` s   | j  j | |  S(   u@    Handle a PATCH-DOC, return a Future with work to be scheduled. (   Rb   Rj   (   Rc   R\   RA   (    (    s3   lib/python2.7/site-packages/bokeh/server/session.pyt   patch  s    N(%   t   __name__t
   __module__t   __doc__R   R7   t   propertyR4   R8   R   R9   R:   R;   R=   R?   R   R   RB   RD   RF   RG   R   RH   RL   RO   R0   RX   R]   R_   Ra   t   classmethodRd   Rg   Rh   Rj   Rl   RV   Rm   (    (    (    s3   lib/python2.7/site-packages/bokeh/server/session.pyR    c   s>   													
(   u   current_timeu   ServerSession(   Rp   t
   __future__R    R   R   R   t   loggingt	   getLoggerRn   R	   R   t   tornadoR   R   t   util.tornadoR   RQ   R   t   __all__R   R   t   objectR    (    (    (    s3   lib/python2.7/site-packages/bokeh/server/session.pyt   <module>	   s   " 	)	