o
    ßñhÚ%  ã                   @  sº   U d dl mZ d dlmZmZ d dlmZ d dlmZm	Z	 d dl
mZ d dlmZ d dlmZmZmZ erAd dlmZ d d	lmZ eeƒZd
ed< ddd„Zddd„ZG dd„ deƒZdS )é    )Úannotations)ÚTYPE_CHECKINGÚFinal)ÚWeakKeyDictionary)ÚconfigÚutil)Ú
get_logger)Ú
ForwardMsg)Ú	CacheStatÚCacheStatsProviderÚgroup_stats)ÚMutableMapping)Ú
AppSessionr   Ú_LOGGERÚmsgr	   ÚreturnÚstrc                 C  s<   | j dkr| j}|  d¡ t |  ¡ ¡| _ | j |¡ | j S )ao  Computes and assigns the unique hash for a ForwardMsg.

    If the ForwardMsg already has a hash, this is a no-op.

    Parameters
    ----------
    msg : ForwardMsg

    Returns
    -------
    string
        The message's hash, returned here for convenience. (The hash
        will also be assigned to the ForwardMsg; callers do not need
        to do this.)

    Ú Úmetadata)Úhashr   Ú
ClearFieldr   Úcalc_md5ÚSerializeToStringÚCopyFrom)r   r   © r   úW/var/www/vscode/kcb/lib/python3.10/site-packages/streamlit/runtime/forward_msg_cache.pyÚpopulate_hash_if_needed!   s   

r   c                 C  s"   t ƒ }t| ƒ|_|j | j¡ |S )aŒ  Create a ForwardMsg that refers to the given message via its hash.

    The reference message will also get a copy of the source message's
    metadata.

    Parameters
    ----------
    msg : ForwardMsg
        The ForwardMsg to create the reference to.

    Returns
    -------
    ForwardMsg
        A new ForwardMsg that "points" to the original message via the
        ref_hash field.

    )r	   r   Úref_hashr   r   )r   Úref_msgr   r   r   Úcreate_reference_msgA   s   
r   c                   @  sv   e Zd ZdZG dd„ dƒZdd„ Zd$dd	„Zd%dd„Zd&dd„Zd'dd„Z	d(dd„Z
d)dd„Zd*dd„Zd+d!d"„Zd#S ),ÚForwardMsgCachea“  A cache of ForwardMsgs.

    Large ForwardMsgs (e.g. those containing big DataFrame payloads) are
    stored in this cache. The server can choose to send a ForwardMsg's hash,
    rather than the message itself, to a client. Clients can then
    request messages from this cache via another endpoint.

    This cache is *not* thread safe. It's intended to only be accessed by
    the server thread.

    c                   @  sV   e Zd ZdZddd„Zddd	„Zddd„Zddd„Zddd„Zd dd„Z	d!dd„Z
dS )"zForwardMsgCache.Entryz„Cache entry.

        Stores the cached message, and the set of AppSessions
        that we've sent the cached message to.

        r   úForwardMsg | Nonec                 C  s   || _ tƒ | _d S ©N)r   r   Ú_session_script_run_counts)Úselfr   r   r   r   Ú__init__n   s   ÿzForwardMsgCache.Entry.__init__r   r   c                 C  ó
   t  | ¡S r"   ©r   Úrepr_©r$   r   r   r   Ú__repr__t   ó   
zForwardMsgCache.Entry.__repr__Úsessionr   Úscript_run_countÚintÚNonec                 C  s6   | j  |d¡}||k rt d||¡ |}|| j |< dS )a  Adds a reference to a AppSession that has referenced
            this Entry's message.

            Parameters
            ----------
            session : AppSession
            script_run_count : int
                The session's run count at the time of the call

            r   zMNew script_run_count (%s) is < prev_run_count (%s). This should never happen!N)r#   Úgetr   Úerror)r$   r,   r-   Úprev_run_countr   r   r   Úadd_session_refw   s   üz%ForwardMsgCache.Entry.add_session_refÚboolc                 C  s
   || j v S r"   ©r#   ©r$   r,   r   r   r   Úhas_session_ref   r+   z%ForwardMsgCache.Entry.has_session_refc                 C  s   || j |  S )znThe age of the given session's reference to the Entry,
            given a new script_run_count.

            r5   )r$   r,   r-   r   r   r   Úget_session_ref_age   s   z)ForwardMsgCache.Entry.get_session_ref_agec                 C  s   | j |= d S r"   r5   r6   r   r   r   Úremove_session_ref™   s   z(ForwardMsgCache.Entry.remove_session_refc                 C  s   t | jƒdkS )zzTrue if this Entry has references from any AppSession.

            If not, it can be removed from the cache.
            r   )Úlenr#   r)   r   r   r   Úhas_refsœ   s   zForwardMsgCache.Entry.has_refsN)r   r!   ©r   r   ©r,   r   r-   r.   r   r/   )r,   r   r   r4   )r,   r   r-   r.   r   r.   ©r,   r   r   r/   )r   r4   )Ú__name__Ú
__module__Ú__qualname__Ú__doc__r%   r*   r3   r7   r8   r9   r;   r   r   r   r   ÚEntryf   s    





	rC   c                 C  s
   i | _ d S r"   )Ú_entriesr)   r   r   r   r%   £   r+   zForwardMsgCache.__init__r   r   c                 C  r&   r"   r'   r)   r   r   r   r*   ¦   r+   zForwardMsgCache.__repr__r   r	   r,   r   r-   r.   r/   c                 C  s\   t |ƒ | j |jd¡}|du r&t d¡rt |¡}nt d¡}|| j|j< | ||¡ dS )a‹  Add a ForwardMsg to the cache.

        The cache will also record a reference to the given AppSession,
        so that it can track which sessions have already received
        each given ForwardMsg.

        Parameters
        ----------
        msg : ForwardMsg
        session : AppSession
        script_run_count : int
            The number of times the session's script has run

        Nz)global.storeCachedForwardMessagesInMemory)	r   rD   r0   r   r   Ú
get_optionr    rC   r3   )r$   r   r,   r-   Úentryr   r   r   Úadd_message©   s   

zForwardMsgCache.add_messager   r!   c                 C  s   | j  |d¡}|r|jS dS )zíReturn the message with the given ID if it exists in the cache.

        Parameters
        ----------
        hash : str
            The id of the message to retrieve.

        Returns
        -------
        ForwardMsg | None

        N)rD   r0   r   )r$   r   rF   r   r   r   Úget_messageÄ   s   zForwardMsgCache.get_messager4   c                 C  sL   t |ƒ | j |jd¡}|du s| |¡sdS | ||¡}|tt d¡ƒkS )z6Return True if a session has a reference to a message.NFúglobal.maxCachedMessageAge)	r   rD   r0   r   r7   r8   r.   r   rE   )r$   r   r,   r-   rF   Úager   r   r   Úhas_message_referenceÔ   s   z%ForwardMsgCache.has_message_referencec                 C  s@   | j  ¡  ¡ D ]\}}| |¡r| |¡ | ¡ s| j |= qdS )zÌRemove refs for all entries for the given session.

        This should be called when an AppSession is disconnected or closed.

        Parameters
        ----------
        session : AppSession
        N)rD   ÚcopyÚitemsr7   r9   r;   )r$   r,   Úmsg_hashrF   r   r   r   Úremove_refs_for_sessionâ   s   

€ùz'ForwardMsgCache.remove_refs_for_sessionc                 C  st   t  d¡}| j ¡  ¡ D ]+\}}| |¡sq| ||¡}||kr7t dt	|ƒ||¡ | 
|¡ | ¡ s7| j|= qdS )a8  Remove any cached messages that have expired from the given session.

        This should be called each time a AppSession finishes executing.

        Parameters
        ----------
        session : AppSession
        script_run_count : int
            The number of times the session's script has run

        rI   z4Removing expired entry [session=%s, hash=%s, age=%s]N)r   rE   rD   rL   rM   r7   r8   r   ÚdebugÚidr9   r;   )r$   r,   r-   Úmax_agerN   rF   rJ   r   r   r   Ú"remove_expired_entries_for_session÷   s"   

ü
€ðz2ForwardMsgCache.remove_expired_entries_for_sessionc                 C  s   | j  ¡  dS )z"Remove all entries from the cache.N)rD   Úclearr)   r   r   r   rT     s   zForwardMsgCache.clearúlist[CacheStat]c                 C  s   dd„ | j  ¡ D ƒ}t|ƒS )Nc                 S  s2   g | ]\}}t d d|jdur|j ¡ ndd‘qS )ÚForwardMessageCacher   Nr   )Úcategory_nameÚ
cache_nameÚbyte_length)r
   r   ÚByteSize)Ú.0Ú_rF   r   r   r   Ú
<listcomp>   s    ûýÿz-ForwardMsgCache.get_stats.<locals>.<listcomp>)rD   rM   r   )r$   Ústatsr   r   r   Ú	get_stats  s   úzForwardMsgCache.get_statsNr<   )r   r	   r,   r   r-   r.   r   r/   )r   r   r   r!   )r   r	   r,   r   r-   r.   r   r4   r>   r=   )r   r/   )r   rU   )r?   r@   rA   rB   rC   r%   r*   rG   rH   rK   rO   rS   rT   r_   r   r   r   r   r    Y   s    =






$r    N)r   r	   r   r   )r   r	   r   r	   )Ú
__future__r   Útypingr   r   Úweakrefr   Ú	streamlitr   r   Ústreamlit.loggerr   Ústreamlit.proto.ForwardMsg_pb2r	   Ústreamlit.runtime.statsr
   r   r   Úcollections.abcr   Ústreamlit.runtime.app_sessionr   r?   r   Ú__annotations__r   r   r    r   r   r   r   Ú<module>   s   

 