class_docstr: Class to help watch a process id to detect when it is dead.
code: def is_dead(self) -> bool:
      if not self.check_process_interval or not self.pid:
          return False
      time_now = time.time()
      if (
          self.check_process_last
          and time_now
          < self.check_process_last + self.check_process_interval
      ):
          return False
      self.check_process_last = time_now
  
      # TODO(jhr): check for os.getppid on unix being 1?
      exists = psutil.pid_exists(self.pid)
      if not exists:
          logger.warning(
              f"Internal process exiting, parent pid {self.pid} disappeared"
          )
          return True
      return False
  
imports: import atexit
  import logging
  import os
  import queue
  import sys
  import threading
  import time
  import traceback
  from datetime import datetime
  from typing import TYPE_CHECKING, Any, List, Optional
  import psutil
  import wandb
  from ..interface.interface_queue import InterfaceQueue
  from ..lib import tracelog
  from .None import context, handler, internal_util, sender, writer
label_desc: Use image node_id 2 for calling the ProcessCheck obj's underlying member method code with example usage: obj.is_dead() and returns: False, False, False, True