class_docstr: Periodic Resource updater for Tune.
  
  Initially, all resources are set to 0. The updater will try to update resources
  when (1) init ResourceUpdater (2) call "update_avail_resources", "num_cpus"
  or "num_gpus".
  
  The update takes effect when (1) Ray is initialized (2) the interval between
  this and last update is larger than "refresh_period"
code: def update_avail_resources(
      self, num_retries: int = 5, force: bool = False
  ):
      if not ray.is_initialized():
          return
      if (
          time.time() - self._last_resource_refresh
          < self._refresh_period
          and not force
      ):
          return
      logger.debug("Checking Ray cluster resources.")
      resources = None
      for i in range(num_retries):
          if i > 0:
              logger.warning(
                  f"Cluster resources not detected or are 0. Attempt #{i + 1}...",
              )
              time.sleep(0.5)
          resources = ray.cluster_resources()
          if resources:
              break
  
      if not resources:
          # NOTE: This hides the possibility that Ray may be waiting for
          # clients to connect.
          resources.setdefault("CPU", 0)
          resources.setdefault("GPU", 0)
          logger.warning(
              "Cluster resources cannot be detected or are 0. "
              "You can resume this experiment by passing in `resume=True` to `run`."
          )
  
      resources = resources.copy()
      num_cpus = resources.pop("CPU", 0)
      num_gpus = resources.pop("GPU", 0)
      memory = resources.pop("memory", 0)
      object_store_memory = resources.pop("object_store_memory", 0)
      custom_resources = resources
  
      self._avail_resources = _Resources(
          int(num_cpus),
          int(num_gpus),
          memory=int(memory),
          object_store_memory=int(object_store_memory),
          custom_resources=custom_resources,
      )
      self._last_resource_refresh = time.time()
  
imports: import logging
  import os
  import time
  from collections import namedtuple
  from numbers import Number
  from typing import Any, Dict, Optional
  import ray
  from ray._private.resource_spec import NODE_ID_PREFIX
label_desc: Use image node_id 2 for calling the _ResourceUpdater obj's underlying member method code with example usage: obj.update_avail_resources(num_retries, force) without return types