class_docstr: Periodically fetches new version of params and stores tf.saved_models.
class_docstr_tok: ["Periodically","fetches","new","version","of","params","and","stores","tf.saved_models","."]
code: def _save(self):
      if not self._snapshot_paths:
          # Lazy discovery of already existing snapshots.
          self._snapshot_paths = os.listdir(self._path)
          self._snapshot_paths.sort(reverse=True)
  
      snapshot_location = os.path.join(
          self._path, time.strftime("%Y%m%d-%H%M%S")
      )
      if (
          self._snapshot_paths
          and self._snapshot_paths[0] == snapshot_location
      ):
          logging.info("Snapshot for the current time already exists.")
          return
  
      # To make sure models are captured as close as possible from the same time
      # we gather all the `ModelToSnapshot` in a 1st loop. We then convert/saved
      # them in another loop as this operation can be slow.
      models_and_paths = self._get_models_and_paths(
          path=snapshot_location
      )
      self._snapshot_paths.insert(0, snapshot_location)
  
      for model, saving_path in models_and_paths:
          self._snapshot_model(model=model, saving_path=saving_path)
  
      # Delete any excess snapshots.
      while (
          self._max_to_keep
          and len(self._snapshot_paths) > self._max_to_keep
      ):
          paths.rmdir(
              os.path.join(self._path, self._snapshot_paths.pop())
          )
  
file_path: acme/acme/jax/snapshotter.py
imports: import os
  import time
  from typing import Callable, Dict, List, Optional, Sequence, Tuple
  from absl import logging
  from acme import core
  from acme.jax import types
  from acme.utils import signals
  from acme.utils import paths
  from jax.experimental import jax2tf
  import tensorflow
label_desc: Use image node_id 3 for calling the JAXSnapshotter obj's underlying member method code with example usage: obj._save() without return types