class_docstr: Read-through / write-through cache for MLMD executions.
docstr: Gets execution either from cache or, upon cache miss, from MLMD.
docstr_tok: ["Gets","execution","either","from","cache","or",",","upon","cache","miss",",","from","MLMD","."]
code: def get_execution(
      self, mlmd_handle: metadata.Metadata, execution_id: int
  ) -> metadata_store_pb2.Execution:
      """Gets execution either from cache or, upon cache miss, from MLMD."""
      with self._lock:
          execution = self._cache.get(execution_id)
      if not execution:
          executions = mlmd_handle.store.get_executions_by_id(
              [execution_id]
          )
          if executions:
              execution = executions[0]
              with self._lock:
                  self._cache[execution_id] = execution
      if not execution:
          raise ValueError(
              f"Execution not found for execution id: {execution_id}"
          )
      return execution
  
imports: import collections
  import contextlib
  import copy
  import threading
  import typing
  from typing import Callable, Iterator, MutableMapping, Optional
  import cachetools
  from tfx.orchestration import metadata
  from google.protobuf.internal import containers
  from ml_metadata.proto import metadata_store_pb2
label_desc: Use image node_id 2 for calling the _ExecutionCache obj's underlying member method code with example usage: obj.get_execution(mlmd_handle, execution_id) and returns: execution