class_docstr: Base class for the remote client.
  
  For each training task, there is a global client in the cluster which
  submits jobs to the master node. Different `@parl.remote_class` objects
  connect to the same global client in a training task.
  
  Attributes:
      submit_job_socket (zmq.Context.socket): A socket which submits job to
                                              the master node.
      pyfiles (bytes): A serialized dictionary containing the code of python
                       files in local working directory.
      executable_path (str): File path of the executable python script.
      start_time (time): A timestamp to record the start time of the program.
class_docstr_tok: ["Base","class","for","the","remote","client",".","For","each","training","task",",","there","is","a","global","client","in","the","cluster","which","submits","jobs","to","the","master","node",".","Different","`","@","parl.remote_class","`","objects","connect","to","the","same","global","client","in","a","training","task",".","Attributes",":","submit_job_socket","(","zmq.Context.socket",")",":","A","socket","which","submits","job","to","the","master","node",".","pyfiles","(","bytes",")",":","A","serialized","dictionary","containing","the","code","of","python","files","in","local","working","directory",".","executable_path","(","str",")",":","File","path","of","the","executable","python","script",".","start_time","(","time",")",":","A","timestamp","to","record","the","start","time","of","the","program","."]
code: def _update_client_status_to_master(self):
      while self.connected_to_master:
          elapsed_time = datetime.timedelta(
              seconds=int(time.time() - self.start_time)
          )
          client_status = {
              "file_path": self.executable_path,
              "actor_num": self.actor_num.value,
              "time": str(elapsed_time),
              "log_monitor_url": self.log_monitor_url,
          }
  
          self.lock.acquire()
          try:
              self.submit_job_socket.send_multipart(
                  [
                      remote_constants.CLIENT_STATUS_UPDATE_TAG,
                      to_byte(self.reply_master_heartbeat_address),
                      cloudpickle.dumps(client_status),
                  ]
              )
              message = self.submit_job_socket.recv_multipart()
          except zmq.error.Again as e:
              self.connected_to_master = False
          finally:
              self.lock.release()
  
          time.sleep(remote_constants.HEARTBEAT_INTERVAL_S)
  
imports: import cloudpickle
  import datetime
  import os
  import socket
  import sys
  import threading
  import zmq
  import parl
  import time
  import glob
  import multiprocessing
  from parl.utils import to_str, to_byte, get_ip_address, logger, isnotebook
  from parl.remote.utils import get_subfiles_recursively
  from parl.remote import remote_constants
  from parl.remote.grpc_heartbeat import HeartbeatServerThread, HeartbeatServerProcess
  from parl.remote.utils import get_version
label_desc: Use image node_id 8 for calling the Client obj's underlying member method code with example usage: obj._update_client_status_to_master() without return types