code: def run(self):
      episode = 0
      steps_done = 0
      total_reward = 0
      stop_training = False
  
      while episode < self.n_episodes and not stop_training:
          if self.model_update_queue.qsize() > 0:
              while self.model_update_queue.qsize() > 0:
                  model = self.model_update_queue.get()
  
              self.agent.model.update_networks(model)
  
          state = self.env.reset()
          done = False
  
          print(
              "====      EPISODE ID ({}/{}): {}      ====".format(
                  episode + 1, self.n_episodes, self.env.episode_id
              )
          )
  
          while not done:
              threshold = self.eps_end + (
                  self.eps_start - self.eps_end
              ) * np.exp(-steps_done / self.eps_decay_steps)
              action = self.agent.get_action(state, threshold=threshold)
              next_state, reward, done, _ = self.env.step(action)
  
              self.memory_queue.put(
                  (state, action, reward, next_state, done)
              )
  
              state = next_state
              total_reward += reward
              steps_done += 1
  
              if self.n_steps and steps_done >= self.n_steps:
                  stop_training = True
                  done = True
  
              if steps_done % self.update_target_every == 0:
                  self.agent.update_target_network()
  
          episode += 1
  
      mean_reward = total_reward / steps_done
  
      self.done_queue.put(mean_reward)
  
imports: from deprecated import deprecated
  import numpy
  from typing import Callable
  from multiprocessing import Process, Queue
label_desc: Use image node_id 2 for calling the ParallelDQNTrainer obj's underlying member method code with example usage: obj.run() without return types