Starts automatically reloading the given multiplexer.

  If `load_interval` is positive, the thread will reload the multiplexer
  by calling `ReloadMultiplexer` every `load_interval` seconds, starting
  immediately. Otherwise, reloads the multiplexer once and never again.

  Args:
    multiplexer: The `EventMultiplexer` to add runs to and reload.
    path_to_run: A dict mapping from paths to run names, where `None` as the run
      name is interpreted as a run name equal to the path.
    load_interval: An integer greater than or equal to 0. If positive, how many
      seconds to wait after one load before starting the next load. Otherwise,
      reloads the multiplexer once and never again (no continuous reloading).
    reload_task: Indicates the type of background task to reload with.

  Raises:
    ValueError: If `load_interval` is negative.

def start_reloading_multiplexer(multiplexer, path_to_run, load_interval,
                                reload_task):
  """Starts automatically reloading the given multiplexer.

  If `load_interval` is positive, the thread will reload the multiplexer
  by calling `ReloadMultiplexer` every `load_interval` seconds, starting
  immediately. Otherwise, reloads the multiplexer once and never again.

  Args:
    multiplexer: The `EventMultiplexer` to add runs to and reload.
    path_to_run: A dict mapping from paths to run names, where `None` as the run
      name is interpreted as a run name equal to the path.
    load_interval: An integer greater than or equal to 0. If positive, how many
      seconds to wait after one load before starting the next load. Otherwise,
      reloads the multiplexer once and never again (no continuous reloading).
    reload_task: Indicates the type of background task to reload with.

  Raises:
    ValueError: If `load_interval` is negative.
  """
  if load_interval < 0:
    raise ValueError('load_interval is negative: %d' % load_interval)

  def _reload():
    while True:
      start = time.time()
      logger.info('TensorBoard reload process beginning')
      for path, name in six.iteritems(path_to_run):
        multiplexer.AddRunsFromDirectory(path, name)
      logger.info('TensorBoard reload process: Reload the whole Multiplexer')
      multiplexer.Reload()
      duration = time.time() - start
      logger.info('TensorBoard done reloading. Load took %0.3f secs', duration)
      if load_interval == 0:
        # Only load the multiplexer once. Do not continuously reload.
        break
      time.sleep(load_interval)

  if reload_task == 'process':
    logger.info('Launching reload in a child process')
    import multiprocessing
    process = multiprocessing.Process(target=_reload, name='Reloader')
    # Best-effort cleanup; on exit, the main TB parent process will attempt to
    # kill all its daemonic children.
    process.daemon = True
    process.start()
  elif reload_task in ('thread', 'auto'):
    logger.info('Launching reload in a daemon thread')
    thread = threading.Thread(target=_reload, name='Reloader')
    # Make this a daemon thread, which won't block TB from exiting.
    thread.daemon = True
    thread.start()
  elif reload_task == 'blocking':
    if load_interval != 0:
      raise ValueError('blocking reload only allowed with load_interval=0')
    _reload()
  else:
    raise ValueError('unrecognized reload_task: %s' % reload_task)