class_docstr: Thread that handles experience generation (worker.sample() loop).
code: def run(self):
      try:
          while True:
              logger.info("Generating new batch of experiences.")
              samples = self.rollout_worker.sample()
              metrics = self.rollout_worker.get_metrics()
              if isinstance(samples, MultiAgentBatch):
                  logger.info(
                      "Sending batch of {} env steps ({} agent steps) to "
                      "server.".format(
                          samples.env_steps(), samples.agent_steps()
                      )
                  )
              else:
                  logger.info(
                      "Sending batch of {} steps back to server.".format(
                          samples.count
                      )
                  )
              self.send_fn(
                  {
                      "command": Commands.REPORT_SAMPLES,
                      "samples": samples,
                      "metrics": metrics,
                  }
              )
      except Exception as e:
          logger.error("Error: inference worker thread died!", e)
  
imports: import logging
  import threading
  import time
  from typing import Union, Optional
  from enum import Enum
  import ray.cloudpickle
  from ray.rllib.env.external_env import ExternalEnv
  from ray.rllib.env.external_multi_agent_env import ExternalMultiAgentEnv
  from ray.rllib.env.multi_agent_env import MultiAgentEnv
  from ray.rllib.policy.sample_batch import MultiAgentBatch
  from ray.rllib.utils.annotations import PublicAPI
  from ray.rllib.utils.typing import MultiAgentDict, EnvInfoDict, EnvObsType, EnvActionType
label_desc: Use image node_id 2 for calling the _LocalInferenceThread obj's underlying member method code with example usage: obj.run() without return types