diff --git a/codex-rs/rollout/src/compression.rs b/codex-rs/rollout/src/compression.rs
index d9d08b226..8211f79d6 100644
--- a/codex-rs/rollout/src/compression.rs
+++ b/codex-rs/rollout/src/compression.rs
@@ -24,8 +24,8 @@ static TEMP_COUNTER: AtomicU64 = AtomicU64::new(0);
/// Starts a best-effort background job that compresses cold local rollout files.
///
/// The worker is fire-and-forget: failures are logged, startup is not blocked,
-/// and a process-wide lock under `codex_home` prevents overlapping compression
-/// runs from the same local store.
+/// and a run marker under `codex_home` prevents overlapping or too-frequent
+/// compression runs from the same local store.
pub fn spawn_rollout_compression_worker(codex_home: PathBuf) {
worker::spawn(codex_home)
}
@@ -246,10 +246,10 @@ mod worker {
const TEMP_SUFFIX: &str = ".tmp";
const COMPRESSION_LEVEL: i32 = 3;
const MIN_ROLLOUT_AGE: Duration = Duration::from_secs(7 * 24 * 60 * 60);
- const GLOBAL_LOCK_STALE_AFTER: Duration = Duration::from_secs(6 * 60 * 60);
- const TEMP_FILE_STALE_AFTER: Duration = GLOBAL_LOCK_STALE_AFTER;
+ const RUN_MARKER_STALE_AFTER: Duration = Duration::from_secs(6 * 60 * 60);
+ const TEMP_FILE_STALE_AFTER: Duration = RUN_MARKER_STALE_AFTER;
const WORKER_MAX_RUNTIME: Duration = Duration::from_secs(5 * 60 * 60);
- const LOCK_FILE_NAME: &str = "rollout-compression.lock";
+ const RUN_MARKER_FILE_NAME: &str = "rollout-compression.lock";
const MAX_CONCURRENT_COMPRESSION_JOBS: usize = 2;
#[derive(Default)]
@@ -260,17 +260,18 @@ mod worker {
failed: usize,
}
- struct CompressionLock {
+ pub(super) struct CompressionRunMarker {
path: PathBuf,
+ remove_on_drop: bool,
}
- impl CompressionLock {
- fn try_acquire(codex_home: &Path) -> io::Result