fix(evidence): lock GC and preflight search ownership

This commit is contained in:
2026-07-12 06:07:30 +02:00
parent d21aac9151
commit efcb0deb31
7 changed files with 55 additions and 6 deletions
+12
View File
@@ -10,6 +10,7 @@ import stat
import shutil
import uuid
import hashlib
import threading
from datetime import UTC, datetime
from pathlib import Path
from contextlib import contextmanager
@@ -49,6 +50,7 @@ class CorpusStore:
self.active_path = self.root / "ACTIVE"
self._replace = os.replace
self._fsync_directory = self._sync_root
self._lock_state = threading.local()
self._ensure_root()
def _ensure_root(self) -> None:
@@ -61,6 +63,14 @@ class CorpusStore:
@contextmanager
def writer_lock(self):
depth = getattr(self._lock_state, "depth", 0)
if depth:
self._lock_state.depth = depth + 1
try:
yield
finally:
self._lock_state.depth -= 1
return
lock_path = self.root / ".writer.lock"
fd = os.open(lock_path, os.O_RDWR | os.O_CREAT | os.O_NOFOLLOW | os.O_CLOEXEC, 0o600)
try:
@@ -68,8 +78,10 @@ class CorpusStore:
if not stat.S_ISREG(info.st_mode) or info.st_uid != os.getuid() or info.st_nlink != 1:
raise UnsafeCorpusPath("corpus writer lock is unsafe")
fcntl.flock(fd, fcntl.LOCK_EX)
self._lock_state.depth = 1
yield
finally:
self._lock_state.depth = 0
fcntl.flock(fd, fcntl.LOCK_UN)
os.close(fd)