
    -eL.                       d Z ddlmZ ddlZ ej        e          ZddlZddlZddl	m	Z	 ddl
mZ ddlmZmZmZmZmZ ddlmZ erddlmZ d	d
lmZ d	dlmZ ddlmZ er&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%m&Z& ddl'm(Z( dZ) ed          Z* ededef                   Z+d dZ,d!dZ- G d d          Z.dS )"z( Provides the ``ServerSession`` class.

    )annotationsN)copywraps)TYPE_CHECKINGAny	AwaitableCallableTypeVar)locks)IOLoop   )ConnectionLost)generate_jwt_token   )DocumentCallbackGroup)ID)Document)DocumentPatchedEvent)messages)CallbackSessionCallback)ServerConnection)current_timeServerSessionTF.)boundfuncreturnc                >     t                     d fd            }|S )zDecorator 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.
    selfr   c                0  K   | j         rt                              d           d S |                                  	 | j                                         d {V 5  | j        t          d          g | _        	  | g|R i |}t          j	        |          r| d {V }| j        }d | _        n# | j        }d | _        w xY w|D ]
}| d {V  	 d d d            n# 1 swxY w Y   || 
                                 S # | 
                                 w xY w)Nz6Ignoring locked callback on already-destroyed session.zUinternal class invariant violated: _pending_writes should be None if lock is not held)	destroyedlogdebugblock_expiration_lockacquire_pending_writesRuntimeErrorinspectisawaitableunblock_expiration)r"   argskwargsresultpending_writespr   s         4lib/python3.11/site-packages/bokeh/server/session.py_needs_document_lock_wrapperz:_needs_document_lock.<locals>._needs_document_lock_wrapperM   s      > 	IINOOO4	&z))++++++++  '3& (L M M M')$0!T$888888F*622 . (.
 &*%9N+/D(( &*%9N+/D(////'  AGGGGGGGG#              & ##%%%%D##%%%%sG   C? C:(B1"C1CCC? C""C? %C"&C? ?D)r"   r   r   )r   r5   s   ` r4   _needs_document_lockr6   G   s<     4[[& & & & & [&@ ('    floatc                 .    t          j                    dz  S )zWReturn the time in milliseconds since the epoch as a floating
       point number.
    i  )time	monotonic r7   r4   r   r   t   s     >d""r7   c                     e Zd ZU dZded<   ded<   ded<   dGdHdZedId            ZedJd            ZedKd            Z	edLd            Z
edLd            ZedLd            ZedMd            ZdNdZdNdZdNd ZdNd!ZdOd$ZdOd%ZedMd&            ZedPd(            ZedQd/            ZdRd2ZdSd4ZdTd7ZedUd;            ZdVd<Zd= ZedUd>            ZedWdA            Z edWdB            Z!edXdD            Z"edXdE            Z#dNdFZ$dS )Yr   z^ Hosts an application "instance" (an instantiated Document) for one or more connections.

    zset[ServerConnection]_subscribed_connectionszServerConnection | None_current_patch_connectionzlist[Awaitable[None]] | Noner*   N
session_idr   documentr   io_loopIOLoop | Nonetoken
str | Noner    Nonec                    |t          d          |t          d          | _        | _        | _        | _        t                       _        t                       _        t          j
                     _        d  _         j        j                                        t          |           _        d  _        d _        d _        d _         fd j        j        D             } j                            |           d S )NzSessions must have an idzSessions must have a documentFr   c                :    g | ]}                     |          S r<   )_wrap_session_callback).0cbr"   s     r4   
<listcomp>z*ServerSession.__init__.<locals>.<listcomp>   s'    hhhT88<<hhhr7   )
ValueError_id_token	_document_loopsetr>   r   _last_unsubscribe_timer   Lockr(   r?   	callbackson_change_dispatch_tor   
_callbacksr*   
_destroyed_expiration_requested_expiration_blocked_countsession_callbacksadd_session_callbacks)r"   r@   rA   rB   rD   wrapped_callbackss   `     r4   __init__zServerSession.__init__   s    7888<===!
'*uu$&2nn#Z\\
)-& 66t<<</88#%*")*&hhhht~Gghhh--.?@@@@@r7   c                    | j         S N)rP   r"   s    r4   rA   zServerSession.document   s
    ~r7   c                    | j         S r`   )rN   ra   s    r4   idzServerSession.id   s	    xr7   strc                F    | j         r| j         S t          | j                  S )z* A JWT token to authenticate the session. )rO   r   rc   ra   s    r4   rD   zServerSession.token   s&     ; 	;!$'***r7   boolc                    | j         S r`   )rX   ra   s    r4   r$   zServerSession.destroyed   s
    r7   c                    | j         S r`   rY   ra   s    r4   expiration_requestedz"ServerSession.expiration_requested   s    ))r7   c                    | j         dk    S )Nr   rZ   ra   s    r4   expiration_blockedz ServerSession.expiration_blocked   s    -11r7   intc                    | j         S r`   rl   ra   s    r4   expiration_blocked_countz&ServerSession.expiration_blocked_count   s    --r7   c                    d| _         | j                            |            | `| j                                         | `d S )NT)rX   rP   destroyrW   remove_all_callbacksra   s    r4   rr   zServerSession.destroy   sA    t$$$N,,...OOOr7   c                    d| _         dS )zK Used in test suite for now. Forces immediate expiration if no connections.TNri   ra   s    r4   request_expirationz ServerSession.request_expiration   s    %)"""r7   c                &    | xj         dz  c_         d S )Nr   rl   ra   s    r4   r'   zServerSession.block_expiration   s    &&!+&&&&r7   c                Z    | j         dk    rt          d          | xj         dz  c_         d S )Nr   z0mismatched block_expiration / unblock_expirationr   )rZ   r+   ra   s    r4   r.   z ServerSession.unblock_expiration   s9    )Q..QRRR&&!+&&&&r7   
connectionr   c                :    | j                             |           dS )zgThis should only be called by ``ServerConnection.subscribe_session`` or our book-keeping will be brokenN)r>   addr"   rx   s     r4   	subscribezServerSession.subscribe   s    $((44444r7   c                `    | j                             |           t                      | _        dS )ziThis should only be called by ``ServerConnection.unsubscribe_session`` or our book-keeping will be brokenN)r>   discardr   rS   r{   s     r4   unsubscribezServerSession.unsubscribe   s+    $,,Z888&2nn###r7   c                *    t          | j                  S r`   )lenr>   ra   s    r4   connection_countzServerSession.connection_count   s    4/000r7   r8   c                .    t                      | j        z
  S r`   )r   rS   ra   s    r4   #milliseconds_since_last_unsubscribez1ServerSession.milliseconds_since_last_unsubscribe   s    ~~ ;;;r7   r   Callable[..., T]r/   r   r0   r   c                     ||i |S )zH Asynchronously locks the document and runs the function with it locked.r<   )r"   r   r/   r0   s       r4   with_document_lockedz"ServerSession.with_document_locked   s     tT$V$$$r7   callbackr   c                >     t          dd          rS d fd}|S )NnolockFr/   r   r0   c                 &     j         g| R i |S r`   )r   )r/   r0   r   r"   s     r4   wrapped_callbackz?ServerSession._wrap_document_callback.<locals>.wrapped_callback   s&    ,4,XGGGGGGGr7   )r/   r   r0   r   )getattr)r"   r   r   s   `` r4   _wrap_document_callbackz%ServerSession._wrap_document_callback   sM    8Xu-- 	O	H 	H 	H 	H 	H 	H 	Hr7   r   c                b    t          |          }|                     |j                  |_        |S r`   )r   r   r   	_callback)r"   r   wrappeds      r4   rI   z$ServerSession._wrap_session_callback   s+    x.. 889JKKr7   eventr   c                    |j         | u }| j        t          d          | j        D ];}|r
|| j        u r| j                            |                    |                     <d S )Nzv_pending_writes should be non-None when we have a document lock, and we should have the lock when the document changes)setterr*   r+   r>   r?   appendsend_patch_document)r"   r   may_suppressrx   s       r4   _document_patchedzServerSession._document_patched   s    |t+'   X  Y  Y  Y
 6 	O 	OJ 
d.L L L ''
(F(Fu(M(MNNNN	O 	Or7   messagemsg.pull_doc_reqmsg.pull_doc_replyc                    t                               d| j                   |j                            d|j        d         | j                  S )Nz$Sending pull-doc-reply from session zPULL-DOC-REPLYmsgid)r%   r&   rc   protocolcreateheaderrA   r"   r   rx   s      r4   _handle_pullzServerSession._handle_pull   sF    		DDDEEE"))*:GN7<SUYUbcccr7   c                n    |                      |j                  }| j                            |           d S r`   )rI   r   rW   add_session_callback)r"   r   r   s      r4   _session_callback_addedz%ServerSession._session_callback_added  s3    --en==,,W55555r7   c                D    | j                             |j                   d S r`   )rW   remove_session_callbackr   )r"   r   s     r4   _session_callback_removedz'ServerSession._session_callback_removed  s     //?????r7   c                8    |j                             ||          S )z? Handle a PULL-DOC, return a Future with work to be scheduled. )sessionr   clsr   rx   s      r4   pullzServerSession.pull
       !..w
CCCr7   msg.push_docmsg.okc                    t                               d| j                   |                    | j                   |                    |          S )Nzpushing doc to session )r%   r&   rc   push_to_documentrA   okr   s      r4   _handle_pushzServerSession._handle_push  sG    		7DG77888  ///}}W%%%r7   c                8    |j                             ||          S )z? Handle a PUSH-DOC, return a Future with work to be scheduled. )r   r   r   s      r4   pushzServerSession.push  r   r7   msg.patch_docc                    || _         	 |                    | j        |            d | _         n# d | _         w xY w|                    |          S r`   )r?   apply_to_documentrA   r   r   s      r4   _handle_patchzServerSession._handle_patch  sX    )3&	2%%dmT:::-1D**TD*1111}}W%%%s   , 	5c                8    |j                             ||          S )z@ Handle a PATCH-DOC, return a Future with work to be scheduled. )r   r   r   s      r4   patchzServerSession.patch$  s     !//DDDr7   c                \    | j         j                            t                                 dS )z3 Notify the document that the connection was lost. N)rA   rU   trigger_eventr   ra   s    r4   notify_connection_lostz$ServerSession.notify_connection_lost)  s'    --n.>.>?????r7   )NN)
r@   r   rA   r   rB   rC   rD   rE   r    rF   )r    r   )r    r   )r    rd   )r    rf   )r    rn   )r    rF   )rx   r   r    rF   r    r8   )r   r   r/   r   r0   r   r    r   )r   r   r    r   )r   r   r    r   )r   r   r    rF   )r   r   rx   r   r    r   )r   r   )r   r   rx   r   r    r   )r   r   rx   r   r    r   )%__name__
__module____qualname____doc____annotations__r^   propertyrA   rc   rD   r$   rj   rm   rp   rr   ru   r'   r.   r|   r   r   r   r6   r   r   rI   r   r   r   r   classmethodr   r   r   r   r   r   r<   r7   r4   r   r   z   sp          322266661111A A A A A.    X    X + + + X+    X * * * X* 2 2 2 X2 . . . X.   * * * *, , , ,, , , ,
5 5 5 55 5 5 5
 1 1 1 X1 < < < X< % % % %          
O O O O d d d d6 6 6 6@ @ @ D D D [D & & & &
 D D D [D & & & & E E E [E@ @ @ @ @ @r7   r   )r   r   r    r   r   )/r   
__future__r   logging	getLoggerr   r%   r,   r:   r   	functoolsr   typingr   r   r	   r
   r   tornador   tornado.ioloopr   eventsr   
util.tokenr   rU   r   
core.typesr   document.documentr   document.eventsr   r   r   msgr   r   rx   r   __all__r   r   r6   r   r   r<   r7   r4   <module>r      s>    # " " " " " g!!                                  &%%%%%% $ # # # # # + + + + + + , , , , , , -,,,,,,666666******44444444,,,,,, GCLLGCxS)***'( '( '( '(Z# # # #q@ q@ q@ q@ q@ q@ q@ q@ q@ q@r7   