code: def test_heartbeat_client_exit_with_kwargs(self):
      def server_exit_func():
          print("exit heartbeat server")
          self.server_exited = True
  
      heartbeat_server_thread = HeartbeatServerThread(server_exit_func)
      heartbeat_server_thread.start()
  
      server_address = heartbeat_server_thread.get_address()
  
      arg1_value = 10
  
      def client_exit_func(arg1):
          print("exit heartbeat client")
          assert arg1 == arg1_value
          self.client_exited = True
  
      heartbeat_client_thread = HeartbeatClientThread(
          server_address,
          client_exit_func,
          exit_func_kwargs={"arg1": arg1_value},
      )
      heartbeat_client_thread.start()
  
      time.sleep(remote_constants.HEARTBEAT_RCVTIMEO_S * 2)
  
      # check server and client are still alive after HEARTBEAT_RCVTIMEO_S * 2
      assert heartbeat_server_thread.is_alive()
      assert heartbeat_client_thread.is_alive()
  
      heartbeat_client_thread.exit()  # manually exit the client
  
      # wait for threads exiting
      for _ in range(10):
          if (
              not heartbeat_server_thread.is_alive()
              and not heartbeat_client_thread.is_alive()
          ):
              break
          time.sleep(remote_constants.HEARTBEAT_INTERVAL_S)
  
      # check heartbeat server and client are exited
      assert not heartbeat_server_thread.is_alive()
      assert not heartbeat_client_thread.is_alive()
  
      assert self.server_exited == True
      assert self.client_exited == True
  
file_path: PARL/parl/remote/grpc_heartbeat/tests/heartbeat_client_arguments_test.py
imports: import time
  import unittest
  from parl.remote.grpc_heartbeat import HeartbeatServerThread
  from parl.remote.grpc_heartbeat import HeartbeatClientThread
  from parl.remote import remote_constants
label_desc: Use image node_id 4 for calling the TestHeartbeatClientArguments obj's underlying member method code with example usage: obj.test_heartbeat_client_exit_with_kwargs() without return types