mirror of
https://github.com/openai/codex.git
synced 2026-10-21 17:48:44 +00:00
## What changed - Add `LocalThreadStore::migrate_rollouts` with dry-run and apply modes, optional thread selection, throughput limiting, and per-rollout outcomes. - Canonicalize legacy JSONL records into paginated history while preserving model-visible conversation context, including compressed rollouts and copied fork history. - Publish replacements atomically and journal migrations so interrupted SQLite projections can be recovered. Coordinate migration with rollout compression and skip rollouts with active writers. - Make paginated history a one-way SQLite promotion so stale metadata cannot downgrade a migrated thread. ## Testing - Cover legacy record normalization, dry runs, idempotency, malformed input, compressed rollouts, active writers, interrupted migration recovery, and a cold app-server resume after migration. GitOrigin-RevId: b9991b659f28ebb52da39ce62e8b4e0bae2ba2bb
42 lines
1.5 KiB
Rust
42 lines
1.5 KiB
Rust
//! Coordinates maintenance jobs that replace local rollout files.
|
|
//!
|
|
//! Rollout compression and legacy rollout migration both publish by renaming a replacement over an
|
|
//! existing rollout path. They must not do that at the same time for one Codex home, so they share
|
|
//! this process-scoped, nonblocking file lock.
|
|
//!
|
|
//! This is separate from per-thread writer locks, which protect live rollout appenders. It is also
|
|
//! separate from compression's durable run marker, which throttles how often compression scans.
|
|
|
|
use std::fs;
|
|
use std::fs::File;
|
|
use std::fs::OpenOptions;
|
|
use std::io;
|
|
use std::path::Path;
|
|
|
|
const ROLLOUT_MAINTENANCE_LOCK: &str = "rollout-maintenance.lock";
|
|
|
|
/// Holds exclusive ownership of operations that replace local rollout files.
|
|
pub struct RolloutMaintenanceGuard {
|
|
_file: File,
|
|
}
|
|
|
|
/// Try to exclude rollout compression and migration for one Codex home.
|
|
pub fn try_acquire_rollout_maintenance_lock(
|
|
codex_home: &Path,
|
|
) -> io::Result<Option<RolloutMaintenanceGuard>> {
|
|
let directory = codex_home.join(".tmp");
|
|
fs::create_dir_all(&directory)?;
|
|
let file = OpenOptions::new()
|
|
.read(true)
|
|
.write(true)
|
|
.create(true)
|
|
.truncate(false)
|
|
.open(directory.join(ROLLOUT_MAINTENANCE_LOCK))?;
|
|
|
|
match file.try_lock() {
|
|
Ok(()) => Ok(Some(RolloutMaintenanceGuard { _file: file })),
|
|
Err(std::fs::TryLockError::WouldBlock) => Ok(None),
|
|
Err(std::fs::TryLockError::Error(error)) => Err(error),
|
|
}
|
|
}
|