code: def _target_fn():
      async def update_fn():
          ws_url = _get_ws_url()
          _logger.debug("connecting to web socket %s", ws_url)
          async with websockets.connect(
              ws_url
          ) as websocket:  # pylint: disable=no-member
              while True:
                  await websocket.recv()
                  # Note: I have not seen use cases where the two lines below are needed
                  # Changing '< 0.2' to '< 1' makes the App very sluggish to the end user
                  # Also the implementation can cause the App state to lag behind because only 1 update
                  # is received per 0.2 second (or 1 second).
                  # while (time.time() - last_updated) < 0.2:
                  #     time.sleep(0.05)
  
                  # Todo: Add some kind of throttling. If 10 messages are received within 100ms then
                  # there is no need to trigger the app state changed, request state and update
                  # 10 times.
                  _logger.debug("App State Changed. Running callbacks")
                  _run_callbacks()
  
      asyncio.run(update_fn())
  
file_path: pytorch-lightning/src/lightning/app/frontend/panel/app_state_comm.py
imports: from __future__ import annotations
  import asyncio
  import os
  from threading import Thread
  from typing import Callable
  import websockets
  from lightning.app.core.constants import APP_SERVER_PORT
  from lightning.app.utilities.app_helpers import Logger
label_desc: Use image node_id 4 for calling a global function with example usage: _target_fn() without return types