Skip to main content

lellm_graph/checkpoint/
checkpoint_policy.rs

1//! Checkpoint 策略 — Trigger / Retention 分层。
2//!
3//! v0.5 重构:将原来的 `CheckpointPolicy` enum 拆分为两层正交策略:
4//!
5//! ```text
6//! CheckpointConfig
7//!   ├── TriggerPolicy:    何时保存 Checkpoint
8//!   ├── RetentionPolicy:  保留多少个 Checkpoint
9//!   └── Store:            存储后端(BlobCheckpointStore)
10//! ```
11//!
12//! # 设计原则
13//!
14//! - **正交性**:Trigger 与 Retention 独立组合,互不干扰
15//! - **渐进式**:默认值与 v0.4 行为一致(EveryNode + KeepAll)
16//! - **可扩展**:未来可添加 OnMutation、TimeBased 等策略
17
18use std::time::Duration;
19
20use super::checkpoint::{Checkpoint, CheckpointStoreError, TraceId};
21
22/// Checkpoint 保存回调类型别名。
23pub type CheckpointSaveFn<S> = Box<
24    dyn Fn(
25            Checkpoint<S>,
26            TraceId,
27        ) -> std::pin::Pin<
28            Box<dyn std::future::Future<Output = Result<(), CheckpointStoreError>> + Send>,
29        > + Send
30        + Sync,
31>;
32
33// ─── TriggerPolicy ─────────────────────────────────────────────
34
35/// Checkpoint 触发策略 — 决定何时保存。
36#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
37pub enum TriggerPolicy {
38    /// 每次节点执行后保存(默认,与 v0.4 CheckpointPolicy::EveryNode 一致)
39    #[default]
40    EveryNode,
41    /// 仅在 Barrier 决策后保存
42    BarrierOnly,
43    /// 手动控制 — 调用方显式触发
44    Manual,
45    /// 有新 Mutation 时才保存(无 Mutation 的节点跳过)
46    OnMutation,
47}
48
49// ─── RetentionPolicy ───────────────────────────────────────────
50
51/// Checkpoint 保留策略 — 决定保留多少个。
52#[derive(Debug, Clone, Default, PartialEq, Eq)]
53pub enum RetentionPolicy {
54    /// 保留所有 Checkpoint(默认,与 v0.4 行为一致)
55    #[default]
56    KeepAll,
57    /// 仅保留最新的 N 个
58    KeepLatest(usize),
59    /// 保留指定时间范围内的 Checkpoint
60    TimeBased(Duration),
61}
62
63impl RetentionPolicy {
64    /// 根据策略计算需要保留的数量。
65    ///
66    /// - `KeepAll` → `None`(不修剪)
67    /// - `KeepLatest(n)` → `Some(n)`
68    /// - `TimeBased` → `None`(需要存储层按时间判断,暂不支援自动修剪)
69    pub fn prune_keep(&self) -> Option<usize> {
70        match self {
71            RetentionPolicy::KeepAll => None,
72            RetentionPolicy::KeepLatest(n) => Some(*n),
73            RetentionPolicy::TimeBased(_) => None, // 需要存储层支持
74        }
75    }
76}
77
78// ─── 向后兼容 ──────────────────────────────────────────────────
79
80/// v0.4 的 CheckpointPolicy — 已弃用,请使用 TriggerPolicy。
81#[allow(deprecated)]
82#[deprecated(
83    since = "0.5.0",
84    note = "Use TriggerPolicy instead. EveryNode → TriggerPolicy::EveryNode, \
85            BarrierOnly → TriggerPolicy::BarrierOnly, Manual → TriggerPolicy::Manual"
86)]
87#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
88pub enum CheckpointPolicy {
89    #[default]
90    EveryNode,
91    BarrierOnly,
92    Manual,
93}
94
95#[allow(deprecated)]
96impl From<CheckpointPolicy> for TriggerPolicy {
97    fn from(policy: CheckpointPolicy) -> Self {
98        match policy {
99            CheckpointPolicy::EveryNode => TriggerPolicy::EveryNode,
100            CheckpointPolicy::BarrierOnly => TriggerPolicy::BarrierOnly,
101            CheckpointPolicy::Manual => TriggerPolicy::Manual,
102        }
103    }
104}