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"
docstr: Returns a human readable message for printing to the console.
docstr_tok: ["Returns","a","human","readable","message","for","printing","to","the","console","."]
code: def debug_string(
      self, total_allocated_resources: Dict[str, Any]
  ) -> str:
      """Returns a human readable message for printing to the console."""
      if self._last_resource_refresh > 0:
          (
              used_cpu,
              total_cpu,
              used_gpu,
              total_gpu,
              custom_used_total,
          ) = self._get_used_avail_resources(total_allocated_resources)
  
          if (
              used_cpu > total_cpu
              or used_gpu > total_gpu
              or any(
                  used > total
                  for (used, total) in custom_used_total.values()
              )
          ):
              # If any of the used resources are higher than what we currently think
              # is available, update our state and re-fetch
              self.update_avail_resources(force=True)
              (
                  used_cpu,
                  total_cpu,
                  used_gpu,
                  total_gpu,
                  custom_used_total,
              ) = self._get_used_avail_resources(
                  total_allocated_resources
              )
  
          status = (
              f"Logical resource usage: {used_cpu}/{total_cpu} CPUs, "
              f"{used_gpu}/{total_gpu} GPUs"
          )
          customs = ", ".join(
              f"{used}/{total} {name}"
              for name, (used, total) in custom_used_total.items()
          )
  
          if customs:
              status += f" ({customs})"
          return status
      else:
          return "Logical resource usage: ?"
  
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 4 for calling the _ResourceUpdater obj's underlying member method code with example usage: obj.debug_string(total_allocated_resources) and returns: status, str