class_docstr: Runs forever.
  
  Monitoring the child processes of @gunicorn_master_proc and restarting
  workers occasionally or when files in the plug-in directory has been modified.
  
  Each iteration of the loop traverses one edge of this state transition
  diagram, where each state (node) represents
  [ num_ready_workers_running / num_workers_running ]. We expect most time to
  be spent in [n / n]. `bs` is the setting webserver.worker_refresh_batch_size.
  The horizontal transition at ? happens after the new worker parses all the
  dags (so it could take a while!)
     V ────────────────────────────────────────────────────────────────────────┐
  [n / n] ──TTIN──> [ [n, n+bs) / n + bs ]  ────?───> [n + bs / n + bs] ──TTOU─┘
     ^                          ^───────────────┘
     │
     │      ┌────────────────v
     └──────┴────── [ [0, n) / n ] <─── start
  We change the number of workers by sending TTIN and TTOU to the gunicorn
  master process, which increases and decreases the number of child workers
  respectively. Gunicorn guarantees that on TTOU workers are terminated
  gracefully and that the oldest worker is terminated.
  
  :param gunicorn_master_pid: PID for the main Gunicorn process
  :param num_workers_expected: Number of workers to run the Gunicorn web server
  :param master_timeout: Number of seconds the webserver waits before killing gunicorn master that
      doesn't respond
  :param worker_refresh_interval: Number of seconds to wait before refreshing a batch of workers.
  :param worker_refresh_batch_size: Number of workers to refresh at a time. When set to 0, worker
      refresh is disabled. When nonzero, airflow periodically refreshes webserver workers by
      bringing up new ones and killing old ones.
  :param reload_on_plugin_change: If set to True, Airflow will track files in plugins_folder directory.
      When it detects changes, then reload the gunicorn.
docstr: Send signal to reload the gunicorn configuration.
  
  When gunicorn receive signals, it reloads the configuration,
  start the new worker processes with a new configuration and gracefully
  shutdown older workers.
docstr_tok: ["Send","signal","to","reload","the","gunicorn","configuration",".","When","gunicorn","receive","signals",",","it","reloads","the","configuration",",","start","the","new","worker","processes","with","a","new","configuration","and","gracefully","shutdown","older","workers","."]
code: def _reload_gunicorn(self) -> None:
      """
      Send signal to reload the gunicorn configuration.
  
      When gunicorn receive signals, it reloads the configuration,
      start the new worker processes with a new configuration and gracefully
      shutdown older workers.
      """
      # HUP: Reload the configuration.
      self.gunicorn_master_proc.send_signal(signal.SIGHUP)
      sleep(1)
      self._wait_until_true(
          lambda: self.num_workers_expected
          == self._get_num_workers_running(),
          timeout=self.master_timeout,
      )
  
imports: from __future__ import annotations
  import logging
  import os
  import signal
  import subprocess
  import sys
  import textwrap
  import time
  from contextlib import suppress
  from pathlib import Path
  from time import sleep
  from typing import NoReturn
  import psutil
  from lockfile.pidlockfile import read_pid_from_pidfile
  from airflow import settings
  from airflow.cli.commands.daemon_utils import run_command_with_daemon_option
  from airflow.configuration import conf
  from airflow.exceptions import AirflowException, AirflowWebServerTimeout
  from airflow.utils import cli
  from airflow.utils.cli import setup_locations
  from airflow.utils.hashlib_wrapper import md5
  from airflow.utils.log.logging_mixin import LoggingMixin
  from airflow.utils.providers_configuration_loader import providers_configuration_loaded
label_desc: Use image node_id 9 for calling the GunicornMonitor obj's underlying member method code with example usage: obj._reload_gunicorn() without return types