class_docstr: Executes a blocking function asynchronously on a queue of items.
docstr: Puts `element` asynchronuously onto the underlying data queue.
  
  The write call blocks if the underlying data_queue contains `queue_size`
    elements for over `self._interruptible_interval_secs` second, in which
    case we check if stop has been requested or if there has been an error
    raised on the looper thread. If neither happened, retry enqueue.
  
  Args:
    element: an element to be put into the underlying data queue and dequeued
      asynchronuously for `fn(element)` call.
code: def put(self, element: E) -> None:
      """Puts `element` asynchronuously onto the underlying data queue.
  
      The write call blocks if the underlying data_queue contains `queue_size`
        elements for over `self._interruptible_interval_secs` second, in which
        case we check if stop has been requested or if there has been an error
        raised on the looper thread. If neither happened, retry enqueue.
  
      Args:
        element: an element to be put into the underlying data queue and dequeued
          asynchronuously for `fn(element)` call.
      """
      while not self._should_stop.is_set():
          try:
              self._data.put(
                  element, timeout=self._interruptible_interval_secs
              )
              break
          except queue.Full:
              continue
      else:
          # If `should_stop` has been set, then raises if any has been raised on
          # the background thread.
          self._raise_on_error()
  
file_path: acme/acme/utils/async_utils.py
imports: import queue
  import threading
  from typing import Callable, TypeVar, Generic
  from absl import logging
label_desc: Use image node_id 4 for calling the AsyncExecutor obj's underlying member method code with example usage: obj.put(element) without return types