fix(evidence): lock GC and preflight search ownership
This commit is contained in:
@@ -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)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user