docstr: Disconnect a session. It will stop producing ForwardMsgs.
  
  Differs from close_session because disconnected sessions can be reconnected to
  for a brief window (depending on the SessionManager/SessionStorage
  implementations used by the runtime).
  
  This function may be called multiple times for the same session,
  which is not an error. (Subsequent calls just no-op.)
  
  Parameters
  ----------
  session_id
      The session's unique ID.
  
  Notes
  -----
  Threading: UNSAFE. Must be called on the eventloop thread.
code: def disconnect_session(self, session_id: str) -> None:
      """Disconnect a session. It will stop producing ForwardMsgs.
  
      Differs from close_session because disconnected sessions can be reconnected to
      for a brief window (depending on the SessionManager/SessionStorage
      implementations used by the runtime).
  
      This function may be called multiple times for the same session,
      which is not an error. (Subsequent calls just no-op.)
  
      Parameters
      ----------
      session_id
          The session's unique ID.
  
      Notes
      -----
      Threading: UNSAFE. Must be called on the eventloop thread.
      """
      session_info = self._session_mgr.get_active_session_info(
          session_id
      )
      if session_info:
          # NOTE: Ideally, we'd like to keep ForwardMsgCache refs for a session around
          # when a session is disconnected (and defer their cleanup until the session
          # is garbage collected), but this would be difficult to do as the
          # ForwardMsgCache is not thread safe, and we have no guarantee that the
          # garbage collector will only run on the eventloop thread. Because of this,
          # we clean up refs now and accept the risk that we're deleting cache entries
          # that will be useful once the browser tab reconnects.
          self._message_cache.remove_refs_for_session(
              session_info.session
          )
          self._session_mgr.disconnect_session(session_id)
      self._on_session_disconnected()
  
imports: from __future__ import annotations
  import asyncio
  import time
  import traceback
  from dataclasses import dataclass, field
  from enum import Enum
  from typing import TYPE_CHECKING, Awaitable, Dict, NamedTuple, Optional, Tuple, Type
  from typing_extensions import Final
  from streamlit import config
  from streamlit.logger import get_logger
  from streamlit.proto.BackMsg_pb2 import BackMsg
  from streamlit.proto.ForwardMsg_pb2 import ForwardMsg
  from streamlit.runtime.app_session import AppSession
  from streamlit.runtime.caching import get_data_cache_stats_provider, get_resource_cache_stats_provider
  from streamlit.runtime.caching.storage.local_disk_cache_storage import LocalDiskCacheStorageManager
  from streamlit.runtime.forward_msg_cache import ForwardMsgCache, create_reference_msg, populate_hash_if_needed
  from streamlit.runtime.legacy_caching.caching import _mem_caches
  from streamlit.runtime.media_file_manager import MediaFileManager
  from streamlit.runtime.media_file_storage import MediaFileStorage
  from streamlit.runtime.memory_session_storage import MemorySessionStorage
  from streamlit.runtime.runtime_util import is_cacheable_msg
  from streamlit.runtime.script_data import ScriptData
  from streamlit.runtime.scriptrunner.script_cache import ScriptCache
  from streamlit.runtime.session_manager import ActiveSessionInfo, SessionClient, SessionClientDisconnectedError, SessionManager, SessionStorage
  from streamlit.runtime.state import SCRIPT_RUN_WITHOUT_ERRORS_KEY, SessionStateStatProvider
  from streamlit.runtime.stats import StatsManager
  from streamlit.runtime.uploaded_file_manager import UploadedFileManager
  from streamlit.runtime.websocket_session_manager import WebsocketSessionManager
  from streamlit.watcher import LocalSourcesWatcher
label_desc: Use image node_id 17 for calling the Runtime obj's underlying member method code with example usage: obj.disconnect_session(session_id) without return types