class_docstr: The client monitor watches the cluster status.
  
  Attributes:
      status (dict): A dict to store workers status and clients status.
class_docstr_tok: ["The","client","monitor","watches","the","cluster","status",".","Attributes",":","status","(","dict",")",":","A","dict","to","store","workers","status","and","clients","status","."]
docstr: Update client status with message send from client heartbeat.
  
  Args:
      client_address (str): client ip address.
      client_status (dict): client status information
                            (hostname, file_path, actor_num, elapsed_time).
docstr_tok: ["Update","client","status","with","message","send","from","client","heartbeat",".","Args",":","client_address","(","str",")",":","client","ip","address",".","client_status","(","dict",")",":","client","status","information","(","hostname",",","file_path",",","actor_num",",","elapsed_time",")","."]
code: def update_client_status(self, client_address, client_status):
      """Update client status with message send from client heartbeat.
  
      Args:
          client_address (str): client ip address.
          client_status (dict): client status information
                                (hostname, file_path, actor_num, elapsed_time).
      """
      self.lock.acquire()
      self.status["clients"][client_address] = client_status
      self.lock.release()
  
file_path: PARL/parl/remote/cluster_monitor.py
imports: import cloudpickle
  import threading
  from collections import defaultdict, deque
  from parl.utils import to_str
label_desc: Use image node_id 4 for calling the ClusterMonitor obj's underlying member method code with example usage: obj.update_client_status(client_address, client_status) without return types