• 这个类比较重要 后期细看 ```java public interface CheckpointListener {

      /**

      • Notifies the listener that the checkpoint with the given {@code checkpointId} completed and
      • was committed. *
      • These notifications are “best effort”, meaning they can sometimes be skipped. To behave

      • properly, implementers need to follow the “Checkpoint Subsuming Contract”. Please see the
      • {@link CheckpointListener class-level JavaDocs} for details. *
      • Please note that checkpoints may generally overlap, so you cannot assume that the {@code

      • notifyCheckpointComplete()} call is always for the latest prior checkpoint (or snapshot) that
      • was taken on the function/operator implementing this interface. It might be for a checkpoint
      • that was triggered earlier. Implementing the “Checkpoint Subsuming Contract” (see above)
      • properly handles this situation correctly as well. *
      • Please note that throwing exceptions from this method will not cause the completed

      • checkpoint to be revoked. Throwing exceptions will typically cause task/job failure and
      • trigger recovery. *
      • @param checkpointId The ID of the checkpoint that has been completed.
      • @throws Exception This method can propagate exceptions, which leads to a failure/recovery for
      • the task. Not that this will NOT lead to the checkpoint being revoked. */ void notifyCheckpointComplete(long checkpointId) throws Exception;

        /**

      • This method is called as a notification once a distributed checkpoint has been aborted. *
      • Important: The fact that a checkpoint has been aborted does NOT mean that the data

      • and artifacts produced between the previous checkpoint and the aborted checkpoint are to be
      • discarded. The expected behavior is as if this checkpoint was never triggered in the first
      • place, and the next successful checkpoint simply covers a longer time span. See the
      • “Checkpoint Subsuming Contract” in the {@link CheckpointListener class-level JavaDocs} for
      • details. *
      • These notifications are “best effort”, meaning they can sometimes be skipped. *

      • This method is very rarely necessary to implement. The “best effort” guarantee, together

      • with the fact that this method should not result in discarding any data (per the “Checkpoint
      • Subsuming Contract”) means it is mainly useful for earlier cleanups of auxiliary resources.
      • One example is to pro-actively clear a local per-checkpoint state cache upon checkpoint
      • failure. *
      • @param checkpointId The ID of the checkpoint that has been aborted.
      • @throws Exception This method can propagate exceptions, which leads to a failure/recovery for
      • the task or job. */ default void notifyCheckpointAborted(long checkpointId) throws Exception {} }

    ```