code: def graceful_kill(popen: Popen) -> int | None:
      for retry in [1.0, 5.0, 20.0, 60.0]:
          _logger.info("Gracefully terminating %s...", popen)
  
          if retry > 10:
              _logger.info('Use "terminate" instead of "interrupt".')
              popen.terminate()
          else:
              popen.send_signal(signal.SIGINT)
  
          time.sleep(1.0)  # Wait for the kill to take effect.
  
          retcode = popen.poll()
          if retcode is not None:
              return retcode
  
          _logger.warning(
              "%s still alive. Retry to kill in %d seconds.",
              popen,
              retry,
          )
          time.sleep(retry)
  
      _logger.warning("Force kill process %s...", popen)
      time.sleep(10.0)  # Wait for the kill
      retcode = popen.poll()
      if retcode is not None:
          return retcode
  
      _logger.error("Failed to kill process %s.", popen)
      return None
  
file_path: nni/nni/contrib/training_service/utils.py
imports: from __future__ import annotations
  import logging
  import signal
  import sys
  import time
  from pathlib import Path
  from subprocess import Popen, PIPE
label_desc: Use image node_id 1 for calling a global function with example usage: graceful_kill(popen) and returns: None, retcode, retcode