code: def run(self):
      # unset http_proxy and https_proxy
      if "http_proxy" in os.environ:
          del os.environ["http_proxy"]
      if "https_proxy" in os.environ:
          del os.environ["https_proxy"]
  
      with grpc.insecure_channel(
          self.heartbeat_server_addr,
          options=[
              ("grpc.max_receive_message_length", -1),
              ("grpc.max_send_message_length", -1),
          ],
      ) as channel:
          stub = heartbeat_pb2_grpc.GrpcHeartbeatStub(channel)
  
          while True:
              if self.exit_flag:
                  break
  
              try:
                  if self.stop_tag is not None:
                      message = heartbeat_pb2.Request(
                          tag=self.stop_tag,
                          extra_message=self.stop_message,
                          client_id=self.client_id,
                      )
                      self.exit_flag = True
                  else:
                      message = heartbeat_pb2.Request(
                          tag=remote_constants.HEARTBEAT_TAG,
                          client_id=self.client_id,
                      )
                  response = stub.Send(
                      message,
                      timeout=remote_constants.HEARTBEAT_RCVTIMEO_S,
                  )
  
                  if response.tag == remote_constants.HEARTBEAT_TAG:
                      pass
                  elif (
                      response.tag
                      == remote_constants.HEARTBEAT_OUT_OF_MEMORY_TAG
                  ):
                      logger.error(response.extra_message)
                      break
                  else:
                      raise NotImplementedError
  
              except grpc._channel._InactiveRpcError as e:
                  break
  
              time.sleep(remote_constants.HEARTBEAT_INTERVAL_S)
  
      # heartbeat is exit, call the exit function.
      self.heartbeat_exit_callback_func(
          *self._exit_func_args, **self._exit_func_kwargs
      )
  
file_path: PARL/parl/remote/grpc_heartbeat/heartbeat_client.py
imports: import os
  import grpc
  import time
  import threading
  from parl.remote import remote_constants
  from parl.remote.grpc_heartbeat import heartbeat_pb2
  from parl.remote.grpc_heartbeat import heartbeat_pb2_grpc
  from parl.utils import logger
label_desc: Use image node_id 4 for calling the HeartbeatClientThread obj's underlying member method code with example usage: obj.run() without return types