class_docstr: A monitor which requests the cluster status every 10 seconds.
      
class_docstr_tok: ["A","monitor","which","requests","the","cluster","status","every","10","seconds","."]
code: def run(self):
      master_is_alive = True
      while master_is_alive:
          try:
              self.socket.send_multipart([b"[MONITOR]"])
              msg = self.socket.recv_multipart()
  
              status = pickle.loads(msg[1])
              data = {"workers": [], "clients": []}
              total_vacant_cpus = 0
              total_used_cpus = 0
              total_vacant_gpus = 0
              total_used_gpus = 0
  
              master_idx = None
              for idx, worker in enumerate(status["workers"].values()):
                  worker["load_time"] = list(worker["load_time"])
                  worker["load_value"] = list(worker["load_value"])
                  if worker["hostname"] == "Master":
                      master_idx = idx
                  data["workers"].append(worker)
                  if not self.gpu_cluster:
                      total_used_cpus += (
                          worker["used_cpus"]
                          if "used_cpus" in worker
                          else 0
                      )
                      total_vacant_cpus += (
                          worker["vacant_cpus"]
                          if "vacant_cpus" in worker
                          else 0
                      )
                  else:
                      total_used_gpus += (
                          worker["used_gpus"]
                          if "used_gpus" in worker
                          else 0
                      )
                      total_vacant_gpus += (
                          worker["vacant_gpus"]
                          if "vacant_gpus" in worker
                          else 0
                      )
  
              if master_idx != 0 and master_idx is not None:
                  master_worker = data["workers"].pop(master_idx)
                  data["workers"] = [master_worker] + data["workers"]
  
              if not self.gpu_cluster:
                  data["total_vacant_cpus"] = total_vacant_cpus
                  data["total_cpus"] = (
                      total_used_cpus + total_vacant_cpus
                  )
              else:
                  data["total_vacant_gpus"] = total_vacant_gpus
                  data["total_gpus"] = (
                      total_used_gpus + total_vacant_gpus
                  )
              data["clients"] = list(status["clients"].values())
              data["client_jobs"] = status["client_jobs"]
              self.data = data
              time.sleep(10)
  
          except zmq.error.Again as e:
              master_is_alive = False
              self.socket.close(0)
  
file_path: PARL/parl/remote/monitor.py
imports: import argparse
  import pickle
  import random
  import time
  import zmq
  import threading
  from flask import Flask, render_template, jsonify, request
label_desc: Use image node_id 2 for calling the ClusterMonitor obj's underlying member method code with example usage: obj.run() without return types