class_docstr: Dummy implementation of distributed workers with buffer creates the workers as a list. Once the outputs are to
  be collected, it simply rolls them out in a loop until is has enough to be added to the buffer.
docstr: implementation of
  :class:`~maze.train.parallelization.distributed_actors.base_distributed_workers_with_buffer.BaseDistributedWorkersWithBuffer`
  interface
docstr_tok: ["implementation","of",":","class",":","`","~maze.train.parallelization.distributed_actors.base_distributed_workers_with_buffer.BaseDistributedWorkersWithBuffer","`","interface"]
code: def collect_rollouts(self) -> Tuple[float, float, float]:
      """implementation of
      :class:`~maze.train.parallelization.distributed_actors.base_distributed_workers_with_buffer.BaseDistributedWorkersWithBuffer`
      interface
      """
  
      assert len(self.replay_buffer) >= self.batch_size, (
          f"The replay buffer should hold more transitions ({len(self.replay_buffer)}) than the batch size "
          f"({self.batch_size}) at all times"
      )
  
      start_wait_time = time.time()
  
      for i in range(self.rollouts_per_iteration):
          # Update the policy if a new version of the policy has been published by the learner
          shared_policy_version_counter = (
              self.broadcasting_container.policy_version()
          )
          if (
              self.policy_version_counter
              < shared_policy_version_counter
          ):
              self._worker_policy.load_state_dict(
                  self.broadcasting_container.policy_state_dict()
              )
              self.policy_version_counter = (
                  shared_policy_version_counter
              )
  
          trajectory = self.workers[self.current_worker_idx].rollout(
              policy=self._worker_policy, n_steps=self.n_rollout_steps
          )
  
          if self.split_rollouts_into_transitions:
              self.replay_buffer.add_rollout(trajectory)
          else:
              self.replay_buffer.add_transition(trajectory)
  
          self.current_worker_idx = (
              self.current_worker_idx + 1
              if self.current_worker_idx < len(self.workers) - 1
              else 0
          )
  
          # collect episode statistics
          for step_record in trajectory.step_records:
              if step_record.episode_stats is not None:
                  self.epoch_stats.receive(step_record.episode_stats)
  
      dequeue_time = time.time() - start_wait_time
  
      return 0, 0, dequeue_time
  
file_path: maze/maze/train/parallelization/distributed_actors/dummy_distributed_workers_with_buffer.py
imports: import time
  from typing import Tuple, Dict
  from maze.core.annotations import override
  from maze.core.rollout.rollout_generator import RolloutGenerator
  from maze.perception.perception_utils import convert_to_torch
  from maze.train.parallelization.broadcasting_container import BroadcastingContainer
  from maze.train.parallelization.distributed_actors.base_distributed_workers_with_buffer import BaseDistributedWorkersWithBuffer
label_desc: Use image node_id 5 for calling the DummyDistributedWorkersWithBuffer obj's underlying member method code with example usage: obj.collect_rollouts() and returns: int,  int,  dequeue_time