class_docstr: A thread-safe task queue with duplicate detection.
  
  The life-cycle of a task starts with producers calling `enqueue`. Consumers
  call `dequeue` to obtain the tasks in FIFO order. When processing is complete,
  consumers must release the tasks by calling `task_done`.
class_docstr_tok: ["A","thread-safe","task","queue","with","duplicate","detection",".","The","life-cycle","of","a","task","starts","with","producers","calling","`","enqueue","`",".","Consumers","call","`","dequeue","`","to","obtain","the","tasks","in","FIFO","order",".","When","processing","is","complete",",","consumers","must","release","the","tasks","by","calling","`","task_done","`","."]
docstr: Removes and returns a task from the queue.
  
  Once the processing is complete, queue consumers must call `task_done`.
  
  Args:
    max_wait_secs: If not `None`, waits a maximum of `max_wait_secs` when the
      queue is empty for a task to be enqueued. If no task is present in the
      queue after the wait, `None` is returned. If `max_wait_secs` is `None`
      (default), returns `None` without waiting when the queue is empty.
  
  Returns:
    A `Task` or `None` if the queue is empty.
docstr_tok: ["Removes","and","returns","a","task","from","the","queue",".","Once","the","processing","is","complete",",","queue","consumers","must","call","`","task_done","`",".","Args",":","max_wait_secs",":","If","not","`","None","`",",","waits","a","maximum","of","`","max_wait_secs","`","when","the","queue","is","empty","for","a","task","to","be","enqueued",".","If","no","task","is","present","in","the","queue","after","the","wait",",","`","None","`","is","returned",".","If","`","max_wait_secs","`","is","`","None","`","(","default",")",",","returns","`","None","`","without","waiting","when","the","queue","is","empty",".","Returns",":","A","`","Task","`","or","`","None","`","if","the","queue","is","empty","."]
code: def dequeue(
      self, max_wait_secs: Optional[float] = None
  ) -> Optional[task_lib.Task]:
      """Removes and returns a task from the queue.
  
      Once the processing is complete, queue consumers must call `task_done`.
  
      Args:
        max_wait_secs: If not `None`, waits a maximum of `max_wait_secs` when the
          queue is empty for a task to be enqueued. If no task is present in the
          queue after the wait, `None` is returned. If `max_wait_secs` is `None`
          (default), returns `None` without waiting when the queue is empty.
  
      Returns:
        A `Task` or `None` if the queue is empty.
      """
      try:
          task_id, task = self._queue.get(
              block=max_wait_secs is not None, timeout=max_wait_secs
          )
      except queue.Empty:
          return None
      with self._lock:
          self._pending_tasks_by_id[task_id] = task
      return task
  
file_path: tfx/tfx/orchestration/experimental/core/task_queue.py
imports: import queue
  import threading
  from typing import Optional
  from tfx.orchestration.experimental.core import task
label_desc: Use image node_id 3 for calling the TaskQueue obj's underlying member method code with example usage: obj.dequeue(max_wait_secs) and returns: task, None