class_docstr: Async Mixin on top of implementation of BaseDataLoader. It contains a seperate thread
  which reads batch from self._iterate() and push them in the queue. The self.__iter__() function
  will pop the batch from the queue.
  If async_loader_queue_size is set to 0, the data loader will not work in async mode.
  For example:
      class PytorchAsyncDataLoader(AsyncDataLoaderMixin, PytorchDataLoader):
class_docstr_tok: ["Async","Mixin","on","top","of","implementation","of","BaseDataLoader",".","It","contains","a","seperate","thread","which","reads","batch","from","self._iterate","(",")","and","push","them","in","the","queue",".","The","self.__iter__","(",")","function","will","pop","the","batch","from","the","queue",".","If","async_loader_queue_size","is","set","to","0",",","the","data","loader","will","not","work","in","async","mode",".","For","example",":","class","PytorchAsyncDataLoader","(","AsyncDataLoaderMixin",",","PytorchDataLoader",")",":"]
docstr: Close the async data loader.
docstr_tok: ["Close","the","async","data","loader","."]
code: def close_async_loader(self):
      """
      Close the async data loader.
      """
      print(
          f"close_async_loader[{self.async_loader_queue_size}], Closing the AsyncDataLoaderMixin."
      )
      if self.async_loader_queue_size > 0 and self.started:
          self.finished_event.set()
          c = 0
          while True:
              try:
                  # Drain buffer
                  self.queue.get_nowait()
                  if self.debug_data_loader:
                      print(
                          f"close_async_loader[{self.async_loader_queue_size}], discarded batch #{c} from Queue."
                      )
  
                  c += 1
  
                  # Force break out if hanging. We assume hanging if already pop items more than twice of the size of the queue.
                  if c > max(2 * self.async_loader_queue_size, 200):
                      print(
                          f"close_async_loader: ERROR!!! Force break out after {c} times get_nowait."
                      )
                      break
              except Empty:
                  break
          if self.debug_data_loader:
              print(
                  f"close_async_loader[{self.async_loader_queue_size}], joining..."
              )
  
          self.thread.join()
  
      print(
          f"close_async_loader[{self.async_loader_queue_size}] is closed."
      )
  
file_path: horovod/horovod/data/data_loader_base.py
imports: from queue import Queue, Empty
  from threading import Thread, Event
label_desc: Use image node_id 2 for calling the AsyncDataLoaderMixin obj's underlying member method code with example usage: obj.close_async_loader() without return types