docs: def _event_monitor_loop(region_name, vpc_id,
                          watcher_plugin, health_plugin,
                          iterations, sleep_time,
                          route_check_time_interval=30):
      """
      Monitor queues to receive updates about new route specs or any detected
      failed IPs.
  
      If any of those have updates, notify the health-monitor thread with a
      message on a special queue and also re-process the entire routing table.
  
      The 'iterations' argument allows us to limit the running time of the watch
      loop for test purposes. Not used during normal operation. Also, for faster
      tests, sleep_time can be set to values less than 1.
  
      The 'route_check_time_interval' arguments specifies the number of seconds
      we allow to elapse before forcing a re-check of the VPC routes. This is so
      that accidentally deleted routes or manually broken route tables can be
      fixed back up again on their own.
  
      """
      q_route_spec = watcher_plugin.get_route_spec_queue()
      q_monitor_ips, q_failed_ips, q_questionable_ips = \
                                                  health_plugin.get_queues()
      time.sleep(sleep_time)   # Wait to allow monitor to report results
  
      current_route_spec = {}  # The last route spec we have seen
      all_ips = []             # Cache of IP addresses we currently know about
  
      # Occasionally we want to recheck VPC routes even without other updates.
      # That way, if a route is manually deleted by someone, it will be
      # re-created on its own.
      last_route_check_time    = time.time()
      while not CURRENT_STATE._stop_all:
          try:
              # Get the latest messages from the route-spec monitor and the
              # health-check monitor. At system start the route-spec queue should
              # immediately have been initialized with a first message.
              failed_ips     = utils.read_last_msg_from_queue(q_failed_ips)
              questnbl_ips   = utils.read_last_msg_from_queue(q_questionable_ips)
              new_route_spec = utils.read_last_msg_from_queue(q_route_spec)
  
              if failed_ips:
                  # Store the failed IPs in the shared state
                  CURRENT_STATE.failed_ips = failed_ips
  
              if questnbl_ips:
                  # Store the questionable IPs in the shared state
                  CURRENT_STATE.questionble_ips = questnbl_ips
  
              if new_route_spec:
                  # Store the new route spec in the shared state
                  CURRENT_STATE.route_spec = new_route_spec
                  current_route_spec = new_route_spec
                  # Need to communicate a new set of IPs to the health
                  # monitoring thread, in case the list changed. The list of
                  # addresses is extracted from the route spec. Pass in the old
                  # version of the address list, so that this function can
                  # compare to see if there are any changes to the host list.
                  all_ips = _update_health_monitor_with_new_ips(new_route_spec,
                                                                all_ips,
                                                                q_monitor_ips)
  
              # Spec or list of failed or questionable IPs changed? Update
              # routes...
              # We pass in the last route spec we have seen, since we are also
              # here in case we only have failed/questionable IPs, but no new
              # route spec. This is also called occasionally on its own, so that
              # we can repair any damaged route tables in VPC.
              now = time.time()
              time_for_regular_recheck = \
                      (now - last_route_check_time) > route_check_time_interval
  
              if new_route_spec or failed_ips or questnbl_ips or \
                                                  time_for_regular_recheck:
                  if not new_route_spec and not (failed_ips or questnbl_ips):
                      # Only reason we are here is due to expired timer.
                      logging.debug("Time for regular route check")
  
                  last_route_check_time = now
                  vpc.handle_spec(region_name, vpc_id, current_route_spec,
                                  failed_ips if failed_ips else [],
                                  questnbl_ips if questnbl_ips else [])
  
              # If iterations are provided, count down and exit
              if iterations is not None:
                  iterations -= 1
                  if iterations == 0:
                      break
  
              time.sleep(sleep_time)
          except KeyboardInterrupt:
              # Allow exit via keyboard interrupt, useful during development
              return
          except Exception as e:
              # Of course we should never get here, but if we do, better to log
              # it and keep operating best we can...
              import traceback
              traceback.print_exc()
              logging.error("*** Uncaught exception 1: %s" % str(e))
              return
  
      logging.debug("event_monitor_loop ended: Global stop")