code: def _check_shutdown(self):
      assert self.lock.locked()
      if not self._in_shutdown:
          return
  
      self.lock.release()
  
      # Do not try disconnect() or throw exceptions in self.data_thread.
      # Otherwise deadlock can occur.
      if threading.current_thread().ident == self.data_thread.ident:
          return
  
      from ray.util import disconnect
  
      disconnect()
  
      self.lock.acquire()
  
      if self._last_exception is not None:
          msg = (
              "Request can't be sent because the Ray client has already "
              "been disconnected due to an error. Last exception: "
              f"{self._last_exception}"
          )
      else:
          msg = (
              "Request can't be sent because the Ray client has already "
              "been disconnected."
          )
  
      raise ConnectionError(msg)
  
imports: import math
  import logging
  import queue
  import threading
  import warnings
  import grpc
  from collections import OrderedDict
  from typing import Any, Callable, Dict, TYPE_CHECKING, Optional, Union
  import ray.core.generated.ray_client_pb2
  import ray.core.generated.ray_client_pb2_grpc
  from ray.util.client.common import INT32_MAX, OBJECT_TRANSFER_CHUNK_SIZE, OBJECT_TRANSFER_WARNING_SIZE
  from ray.util.debug import log_once
label_desc: Use image node_id 15 for calling the DataClient obj's underlying member method code with example usage: obj._check_shutdown() without return types