Skip to content

Promote develop to main: Lock menu.ps1's Hub Cache Through hub.lock - #2538

Merged
ptr727 merged 1 commit into
mainfrom
develop
Oct 8, 2026
Merged

ptr727 merged 1 commit into
mainfrom
develop

Conversation

@ptr727

@ptr727 ptr727 commented Oct 8, 2026

Copy link
Copy Markdown
Owner

Summary

Promotes one change from develop.

  • Lock menu.ps1's Hub Cache Through hub.lock So It Coordinates with menu.sh #2537: host-setup/menu.ps1 now locks the shared hub cache through $DIR/hub.lock with FileShare.None, in place of a named .NET Mutex, so it coordinates with menu.sh's flock on the same file. .NET implements FileShare.None as an exclusive flock on Linux, and on Windows it refuses any other open handle. The lock is re-entrant within a session and skipped under -DryRun, matching menu.sh. It waits only where the open's HResult says the file is held. Any other failure fails the task, using the value the task itself returns on failure.

Closes #1094.

Verification

🤖 Generated with Claude Code

…u.sh (#2537)

## Summary

Settles #1094. `menu.ps1` serialized the shared hub cache with a named
.NET `Mutex`, while `menu.sh` takes a `flock` on `$DIR/hub.lock`, so a
menu of each kind sharing one cache directory never saw the other's
lock.

- **`menu.ps1` now locks `hub.lock` itself**, opened with
`FileShare.None`, the shape `bootstrap.ps1`'s `Lock-Directory` already
uses. .NET implements that as `flock(LOCK_EX|LOCK_NB)` on Linux, which
conflicts with `menu.sh`'s shared reader lock and its exclusive writer
lock in both directions. On Windows it refuses any other open handle on
the file. Every caller still takes one exclusive lock, as with the
mutex.
- **The open does not block on either platform, so a held lock is waited
out by retrying.** It retries only where the HResult says the file is
held, measured on pwsh 7.4: `0x80070020` (low word 32, or 33 for a lock
violation) on Windows, and raw errno 11 (`EWOULDBLOCK`) on Linux. Any
other failure, the cache directory's own creation included, fails the
task and returns the caller's own failure value. A `$false` there would
read as exit code 0 to a caller comparing with `-eq`.
- **The lock is re-entrant within a session.** `Invoke-FetchHub` is
reached through `Confirm-HubRoot` from inside a span that already holds
it, which the mutex allowed and a second open of the file would not.
- **`-DryRun` runs unlocked**, matching `menu.sh`'s
`hub_read_lock_acquire`, since a dry run never fetches or reads the
cache and must not create the directory or the lock file.

## Verification

- `TestPowerShellMenuHubLock`, 7 cases. On Linux (pwsh 7.4.2 in the
offline `python:3.12-slim` image): all 7 pass, including the two
cross-tool cases, a shared `flock` making the menu wait and the menu's
lock refusing a shared `flock`. On Windows (pwsh 7, from Git Bash): 5
pass, and the 2 Linux-only cases skip.
- Mutations, each failing the suite: `FileShare.Read` in place of `None`
(3 failures on Linux), the re-entrancy guard removed (the nested case
times out), and the `New-Item` catch removed.
- `tests.test_bootstrap` passes on Windows. ruff, mypy,
PSScriptAnalyzer, the prose gate, and the EOL gate are clean.
- Three local strict-review passes. The first two raised five findings:
dry run writing files, an unbounded wait on any plain `IOException`, an
uncaught directory-creation failure ending the session, and two test
gaps. Four were fixed in this branch. One was declined: a test for a
non-contention `IOException`, which no portable fixture produces. The
wait tests cover that classification from the other side. The third pass
raised nothing.

The `comments` label stands for the new lock's comments.

Closes #1094 on promotion.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Copilot AI lite review requested due to automatic review settings October 8, 2026 14:39
@coderabbitai

coderabbitai Bot commented Oct 8, 2026

Copy link
Copy Markdown

Important

  • 🔍 Trigger review

This repository does not receive automatic reviews because it has fewer than 10 stars.

⚙️ Run configuration
  • Configuration used: Repository: ptr727/ProjectTemplate/.coderabbit.yaml
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: b40a3f4a-f451-4219-a99e-fc2b2e00c7ca
  • Autopilot · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@codecov

codecov Bot commented Oct 8, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 58.40%. Comparing base (afc77cb) to head (382c0cc).
⚠️ Report is 329 commits behind head on main.

Additional details and impacted files
@@           Coverage Diff           @@
##             main    #2538   +/-   ##
=======================================
  Coverage   58.40%   58.40%           
=======================================
  Files          16       16           
  Lines        8090     8090           
=======================================
  Hits         4725     4725           
  Misses       3365     3365           
Flag Coverage Δ
python-3.13 58.40% <ø> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔵 Needs a closer look

Cross-platform locking and cleanup under concurrent sessions warrant final human review.

0 open findings

What changed in this PR

This promotion brings the shared hub-cache lock from develop to main, so the PowerShell and shell menus coordinate when they use the same cache directory.

Changes:

  • Replace menu.ps1's named mutex with a lock on hub.lock.
  • Add tests for contention, failure paths, dry runs, re-entry, and Linux interoperability.
File Description
tests/​test_bootstrap.py Adds behavioral tests for the PowerShell lock.
host-setup/​menu.ps1 Uses a shared lock file for hub-cache operations.

🧠 Review effort: Lite


Give feedback about Copilot approvals in this survey to enter a drawing for a $150 gift card.

@ptr727
ptr727 merged commit d2a415c into main Oct 8, 2026
13 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

host-setup: menu.sh and menu.ps1 hub-cache locks do not coordinate across tools

2 participants