code: def monitor_keepalive(context, keepalive_address):
      """The keepalive socket should send a regular heartbeat telling workers
      to stay alive. This will stop if the parent process crashes.
      If we see no keepalive message in 15 seconds we take that as a bad
      omen and attempt to gracefully shut down the worker processes.
  
      The same socket also broadcasts the shutdown notification, so we watch
      for that too. The main worker thread should pick that up and shut down
      the next time it makes a request, but this can take a while. Therefore we
      also apply a timeout and cease work manually if the processes don't
      respond to the kill signal quickly enough.
  
      Note that if CellProfiler is paused in debug mode during an analysis, this
      can cause the workers to exit. Use test mode for testing or only debug on
      the worker threads."""
      keepalive_socket = context.socket(zmq.SUB)
      keepalive_socket.connect(keepalive_address)
      keepalive_socket.setsockopt(zmq.SUBSCRIBE, b"")
  
      # Send a message back when we've set this thread up
      deadman_socket = context.socket(zmq.PAIR)
      deadman_socket.connect(DEADMAN_START_ADDR)
      deadman_socket.send(DEADMAN_START_MSG)
      deadman_socket.close()
  
      missed = 0
      while missed < 3:
          event = keepalive_socket.poll(5000)
          if not event:
              missed += 1
              LOGGER.warning(
                  f"Worker failed to receive communication for"
                  f" {5 * missed} seconds"
              )
          else:
              missed = 0
              msg = keepalive_socket.recv()
              if msg == NOTIFY_STOP:
                  break
      # Stop has been called, we must manually close our sockets before the
      # main thread can exit.
      keepalive_socket.close()
      if missed >= 3:
          # Parent is dead, hard kill
          LOGGER.critical(
              "Worker stopped receiving communication from "
              "CellProfiler, shutting down now"
          )
      else:
          # Stop signal captured, give some time to shut down gracefully.
          time.sleep(10)
      LOGGER.info("Cancelling worker")
      # hard exit after 10 seconds unless app exits
  
      for m in all_measurements:
          try:
              m.close()
          except:
              pass
      LOGGER.error("Worker failed to stop gracefully, forcing exit now")
      os._exit(0)
  
file_path: CellProfiler/src/subpackages/core/cellprofiler_core/worker/__init__.py
imports: import logging
  import os
  import sys
  import psutil
  import pkg_resources
  from cellprofiler_core.constants.worker import DEADMAN_START_ADDR, DEADMAN_START_MSG, NOTIFY_STOP, all_measurements, NOTIFY_ADDR
  from cellprofiler_core.preferences import set_always_continue, set_conserve_memory
  from cellprofiler_core.worker._worker import Worker
  import time
  import threading
  import zmq
  import numpy
label_desc: Use image node_id 3 for calling a global function with example usage: monitor_keepalive(context, keepalive_address) without return types