class_docstr: A thread safe, TTL cache of node provider availability. We don't use
  cachetools.TTLCache because it always sets the expiration time relative to
  insertion time, but in our case, we want entries to expire relative to when
  the node creation was attempted (and entries aren't necessarily added in
  order). We want the entries to expire because the information grows stale
  over time.
class_docstr_tok: ["A","thread","safe",",","TTL","cache","of","node","provider","availability",".","We","do","n't","use","cachetools.TTLCache","because","it","always","sets","the","expiration","time","relative","to","insertion","time",",","but","in","our","case",",","we","want","entries","to","expire","relative","to","when","the","node","creation","was","attempted","(","and","entries","are","n't","necessarily","added","in","order",")",".","We","want","the","entries","to","expire","because","the","information","grows","stale","over","time","."]
docstr: A cache that tracks the availability of nodes and throw away
  entries which have grown too stale.
  
  Args:
    timer: A function that returns the current time in seconds.
    ttl: The ttl from the insertion timestamp of an entry.
docstr_tok: ["A","cache","that","tracks","the","availability","of","nodes","and","throw","away","entries","which","have","grown","too","stale",".","Args",":","timer",":","A","function","that","returns","the","current","time","in","seconds",".","ttl",":","The","ttl","from","the","insertion","timestamp","of","an","entry","."]
code: def __init__(
      self,
      timer: Callable[[], float] = time.time,
      ttl: float = AUTOSCALER_NODE_AVAILABILITY_MAX_STALENESS_S,
  ):
      """A cache that tracks the availability of nodes and throw away
      entries which have grown too stale.
  
      Args:
        timer: A function that returns the current time in seconds.
        ttl: The ttl from the insertion timestamp of an entry.
      """
      self.timer = timer
      self.ttl = ttl
      # Mapping from node type to (eviction_time, record)
      self.store: Dict[str, Tuple[float, NodeAvailabilityRecord]] = {}
      # A global lock to simplify thread safety handling.
      self.lock = threading.RLock()
  
file_path: ray/python/ray/autoscaler/_private/node_provider_availability_tracker.py
imports: import threading
  import time
  from dataclasses import dataclass
  from typing import Callable, Dict, Optional, Tuple
  from ray.autoscaler._private.constants import AUTOSCALER_NODE_AVAILABILITY_MAX_STALENESS_S
  from ray.autoscaler.node_launch_exception import NodeLaunchException
label_desc: Use image node_id 1 to create a new NodeProviderAvailabilityTracker object  with example: obj = NodeProviderAvailabilityTracker(timer, ttl)