Prevent concurrent lockfile conflicts using flock and add backup#851
Conversation
Pull Request Test Coverage Report for Build 16203386079Details
💛 - Coveralls |
contrib/test.sh
Outdated
| flock 9 | ||
|
|
||
| # Backup original lockfile | ||
| if [ -f "LOCKFILE" ]; then |
There was a problem hiding this comment.
Do you really intend to check for the literal string "LOCKFILE" ? . if you meant the variable , then you forgot the "$" character
There was a problem hiding this comment.
Thanks for pointing it out!
3dd8fa1 to
78d42ee
Compare
contrib/test.sh
Outdated
| LOCKFILE_LOCK=".cargo.lock.flock" | ||
|
|
||
| # Acquire file lock to prevent concurrent modification | ||
| exec 9>"$LOCKFILE_LOCK" |
There was a problem hiding this comment.
not sure what this is trying to do, but exec is definitely the wrong thing here, it replaces the current shell script with the program 9 which should not normally exist
| exec 9>"$LOCKFILE_LOCK" | |
| touch "$LOCKFILE_LOCK" |
contrib/test.sh
Outdated
|
|
||
| # Acquire file lock to prevent concurrent modification | ||
| exec 9>"$LOCKFILE_LOCK" | ||
| flock 9 |
There was a problem hiding this comment.
this would need to be something like:
(
flock 9
...
) 9>"$LOCKFILE_LOCK"() 9>"$LOCKFILE_LOCK" creates a subshell, opening $LOCKFILE_LOCK for writing as file descriptor 9 and then forking the current program
within the subshell, flock can then inherit file descriptor 9 from the subshell, creating the locking behavior
the ... represents the entirety of the test script, i.e. all the commands that need to be protected by the lock
contrib/test.sh
Outdated
| fi | ||
|
|
||
| # Restore the original lockfile on exit | ||
| trap 'if [ -f "$LOCKFILE_BAK" ]; then mv "$LOCKFILE_BAK" "$LOCKFILE"; fi; flock -u 9' EXIT |
There was a problem hiding this comment.
| trap 'if [ -f "$LOCKFILE_BAK" ]; then mv "$LOCKFILE_BAK" "$LOCKFILE"; fi; flock -u 9' EXIT | |
| trap '[ -f "$LOCKFILE_BAK" ] && mv "$LOCKFILE_BAK" "$LOCKFILE"' EXIT |
since the file descriptor will be closed after the subshell exits, there's no need to unlock
make sure the trap command is within the ( ... ) subshell, or there will be a race condition and the lock will be dropped before restoring
contrib/test.sh
Outdated
|
|
||
| # Backup original lockfile | ||
| if [ -f "$LOCKFILE" ]; then | ||
| cp "$LOCKFILE" "$LOCKFILE_BAK" |
There was a problem hiding this comment.
this seems a bit more intuitive to me but doesn't really matter:
| cp "$LOCKFILE" "$LOCKFILE_BAK" | |
| mv "$LOCKFILE" "$LOCKFILE_BAK" |
78d42ee to
ddb20cb
Compare
nothingmuch
left a comment
There was a problem hiding this comment.
i as a little confused when no Cargo.lock.bak was present because it's cargo.lock.bak
other than that, tACK, tested concurrently, including interrupting
contrib/test.sh
Outdated
| LOCKFILE_BAK="cargo.lock.bak" | ||
| LOCKFILE_LOCK=".cargo.lock.flock" |
There was a problem hiding this comment.
| LOCKFILE_BAK="cargo.lock.bak" | |
| LOCKFILE_LOCK=".cargo.lock.flock" | |
| LOCKFILE_BAK="Cargo.lock.bak" | |
| LOCKFILE_LOCK=".Cargo.lock.flock" |
f72f3e1 to
79316f1
Compare
- Added a file lock using `flock` to ensure only one test script modifies Cargo.lock at a time - Created a backup of Cargo.lock before overwriting it - Added an exit trap to restore the original lockfile and release the lock Add comment explaining file lock workaround due to MSRV constraints
79316f1 to
8c9bc73
Compare
Summary
This PR introduces a safe and stable mechanism to manage Cargo.lock during testing across multiple scripts.
This prevents race conditions and corruption when running tests concurrently
closes #773