Pre-alpha 文档
依据持久化的全局顺序调度租户。
编译不可变 Weight、预约 Replica-global Slot、公开精确 Starvation Bound,并安全保留 Lost-ACK Evidence。
编译一个不可变加权 Policy
StateKnot 按精确 Tenant ID 排序,编译确定性 Smooth Weighted Round Robin Cycle,校验所有配置 Count,并计算每个 Tenant 最大的环形 Selection Gap。硬上界为每个 Shard 1,024 个 Tenant、Weight 1–1,024,以及 4,096 个总 Slot。
let tenant_a = TenantId::try_from("tenant-a")?;
let tenant_b = TenantId::try_from("tenant-b")?;
let policy = WeightedFairnessPolicy::new(
SchedulerShardId::try_from("primary-v1")?,
[
TenantFairnessWeight::new(tenant_a, 3)?,
TenantFairnessWeight::new(tenant_b.clone(), 1)?,
],
)?;
let bound = policy
.starvation_bound(&tenant_b)
.expect("tenant-b was registered in this policy");
assert!(bound.maximum_reservations_until_selection() <= 4); 该比例适用于 Scheduling Opportunity,不适用于 Token Spend、CPU Time、Money 或 Completed Run。Tenant、Weight、Ordering 或 Algorithm 变化时,必须使用新 Shard Identity 并执行显式 Rollout。
先全局预约,再本地扫描
-
注册
DurableFairScheduler::register在任何 Run Claim 前,把完全相同的 Policy Byte 绑定到一个 Shard。 -
预约
每个 Replica 分配一个稳定 UUIDv7 Reservation,并且只推进一次短 PostgreSQL Cursor Transaction。
-
选择
Durable Slot 通过不可变本地 Cycle 映射到且只映射到一个 Tenant Queue。
-
执行 Tick
现有 Tenant-isolated Scheduler 只为该 Tenant 扫描、Claim,并最多执行一个 Run。
Queue 为空或输掉 Contention 时 Reservation 仍会被消费,不会转给 Busy Tenant。这保持 Global Order,并防止 Work-conserving Shortcut 偷走其他 Tenant 的 Share。
测量真实环形 Bound
TenantStarvationBound 是两次 Selection 之间最大的 Global Reservation
数,包含命中 Tenant 的 Slot。它来自编译后的 Cycle,而不是 Ratio 估算。必须同时监控
Selection Gap 与 Successful-claim/Service Lag, 因为 Queue Contention 在公平
Selection 后仍可能阻止工作。
Reservation Evidence 必须长于所有 Retry
Migration 14 保存不可变 Reservation Row,使 Database ACK 丢失后仍返回原
Sequence 与 Slot。Retention 使用 Database Clock、Indexed Oldest-first
Candidate 和
FOR UPDATE SKIP LOCKED,绝不修改 Policy 或 Cursor State。
let policy = SchedulerFairnessRetentionPolicy::new(
Duration::from_secs(24 * 60 * 60),
1_000,
)?;
let report = store
.prune_scheduler_fairness_reservations(policy)
.await?; 支持一小时到 366 天,每个事务最多删除 10,000 行。不得在 Retention Window 后重试 Reservation Identity;Window 必须长于所有 Retry、Incident Replay 与 Audit Requirement。
Policy 变化必须发布新 Shard
Shard ID 永久绑定一份 Canonical Policy。激活 primary-v2 等新 Shard
前先 Drain 旧 Deployment。让两个 Shard Identity 同时处理同一逻辑 Worker Pool,会按设计形成
两套独立 Schedule,使组合后的 Bound 无效。
验证证据
Property Test 验证任意有界 Tenant Order/Weight、精确 Cycle Count、Order Independence 与所有 Circular Bound。PostgreSQL 16/17 Test 覆盖 Immutable Registration、Same-ID / Unique-ID Concurrency、连续 Reservation、Lost ACK、有界 Retention、Migration Integrity,以及四次分布式 Tick 中的 3:1 Share。使用该 pre-alpha Surface 前请阅读完整部署与运维合约。