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: Marks the processing of a task as done.
  
  Consumers should call this method after the task is processed.
  
  Args:
    task: A `Task` object.
  
  Raises:
    RuntimeError: If attempt is made to mark a non-existent or non-dequeued
    task as done.
docstr_tok: ["Marks","the","processing","of","a","task","as","done",".","Consumers","should","call","this","method","after","the","task","is","processed",".","Args",":","task",":","A","`","Task","`","object",".","Raises",":","RuntimeError",":","If","attempt","is","made","to","mark","a","non-existent","or","non-dequeued","task","as","done","."]
code: def task_done(self, task: task_lib.Task) -> None:
      """Marks the processing of a task as done.
  
      Consumers should call this method after the task is processed.
  
      Args:
        task: A `Task` object.
  
      Raises:
        RuntimeError: If attempt is made to mark a non-existent or non-dequeued
        task as done.
      """
      task_id = task.task_id
      with self._lock:
          if task_id not in self._pending_tasks_by_id:
              if task_id in self._task_ids:
                  raise RuntimeError(
                      "Must call `dequeue` before calling `task_done`; task id: {}".format(
                          task_id
                      )
                  )
              else:
                  raise RuntimeError(
                      "Task not present in the queue; task id: {}".format(
                          task_id
                      )
                  )
          self._pending_tasks_by_id.pop(task_id)
          self._task_ids.remove(task_id)
  
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 4 for calling the TaskQueue obj's underlying member method code with example usage: obj.task_done(task) without return types