Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 27 additions & 4 deletions harness2/core/schedule.py
Original file line number Diff line number Diff line change
Expand Up @@ -286,16 +286,39 @@ def _load_old(path: Path) -> dict:
return {}


def _lock_summary(lf) -> None:
"""Exclusive lock on the summary lock file (flock on POSIX, msvcrt on Windows)."""
if os.name == "nt":
import msvcrt

lf.seek(0)
msvcrt.locking(lf.fileno(), msvcrt.LK_LOCK, 1)
else:
import fcntl

fcntl.flock(lf, fcntl.LOCK_EX)


def _unlock_summary(lf) -> None:
if os.name == "nt":
import msvcrt

lf.seek(0)
msvcrt.locking(lf.fileno(), msvcrt.LK_UNLCK, 1)
else:
import fcntl

fcntl.flock(lf, fcntl.LOCK_UN)


def _write_summary(summary_path: Path, res: TaskResult) -> None:
"""Merge `res` into the summary under an flock, atomically, deriving the merged status.

Modes may be written by separate processes, so records accumulate per mode.
"""
import fcntl

lock = summary_path.with_suffix(".lock")
with open(lock, "w") as lf:
fcntl.flock(lf, fcntl.LOCK_EX)
_lock_summary(lf)
try:
merged = res.to_dict()
if summary_path.is_file():
Expand Down Expand Up @@ -325,7 +348,7 @@ def _write_summary(summary_path: Path, res: TaskResult) -> None:
tmp.write_text(json.dumps(merged, indent=2, default=str))
os.replace(tmp, summary_path)
finally:
fcntl.flock(lf, fcntl.LOCK_UN)
_unlock_summary(lf)


def _resolve_libraries(
Expand Down
4 changes: 2 additions & 2 deletions harness2/core/tree.py
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ def read_tree(surface: SurfaceSpec, d: Path | str, *, rejected: list[str] | None
for p in sorted(d.rglob("*")):
if not p.is_file() or "__pycache__" in p.parts:
continue
rel = str(p.relative_to(d))
rel = normalize_rel(str(p.relative_to(d)))
if rel in stubs:
continue
if not is_allowed(surface, rel):
Expand All @@ -164,7 +164,7 @@ def write_tree(surface: SurfaceSpec, tree: Tree, dest: Path | str, *, stubs: boo
for p in sorted(dest.rglob("*"), reverse=True):
if not p.is_file():
continue
rel = str(p.relative_to(dest))
rel = normalize_rel(str(p.relative_to(dest)))
if is_allowed(surface, rel) or rel in stub_set:
p.unlink()
for a in surface.always_on:
Expand Down
Loading