Conversation
…ng through with a debugger. In a debugger the timeout always triggered even if the lock had been successfull obtained.
… it doesn't have a lock as it was a little misleading.
|
Just wondering if you have some time to look at this, as it is currently a blocker for dcli. |
Fork Maintainer Review (Concurrency Primitives)SummaryThis PR does several things at once: (1) adds CorrectnessCritical issue -- behavioral change in the guard loop: The original while (!locked) {
locked = lock.lock();
if (locked) {
_execute(...);
} else {
_wait(...);
locked = lock.lock(); // <-- second lock attempt added here
}
...
}After
The extracted
This is a regression from the original inline code where these mutations correctly affected the loop state.
The new async test ( await NamedLock.guard<void, IntentionalTestException>(
name: 'async test', execution: execution);
Platform Compatibility
RecommendationHOLD -- Do not merge as-is. The two control flow bugs in the guard loop (double I agree with the general direction of the PR description (separating sync vs async guard paths), but the current code has regressions that need to be addressed first. Consider:
|
Concurrency Safety ReviewRace Condition AnalysisCRITICAL: New race condition introduced in the The original while (!locked) {
locked = lock.lock();
if (locked) {
_execute(verbose, locked, execution, lock);
} else {
_wait(verbose, locked, _sleep, _attempt, waiting, now, timeout);
locked = lock.lock(); // <-- Second lock attempt OUTSIDE the while condition
}
// error check runs here regardless
}This introduces a double-lock attempt per iteration in the failure path: the first
Additionally: The
Resource SafetyResource leak risk on timeout: The timeout check was moved from before
Structural ChangesThe split of The The new test RecommendationHOLD -- The Suggested fixes:
|
Detailed Code Review -- named_locks PR #11ChangesThis PR makes several categories of changes:
Code QualityCritical bug -- The
However, because Dart passes these types (Duration, int, String?) by value, none of these mutations propagate back to the caller. This means:
This is a regression from the original inline code where these variables were mutated in place within the Second critical issue -- In the refactored } else {
_wait(verbose, locked, _sleep, _attempt, waiting, now, timeout);
locked = lock.lock(); // <-- second lock attempt after _wait
}But the loop then continues to
The
The TestsThe new
VerdictNEEDS_WORK The core The file extraction (UnixLock/WindowsLock to separate files) and type annotation fixes are clean and welcome. The new async test is a good idea but does not actually validate async await behavior in |
As mentioned I think the way forward is to introduced a new guardSync method and fix the existing guard method so that it is fully async.
At the moment I've stepped back a little as there are a number of issues that I think need to be resolved before we try to fix the async issue.
I've added a linter to the project which has shown up a number of issues that I think need to be fixed.
In particular there is quite a few 'unnecessary statement' errors that look like they are logic errors.
Are you able to have a look at these, as I'm not always certain what you intended.
Additionally some of the code such as the below completer usage, could be simplified by a simple try/catch block.
I'm guessing this was done try and handle sync and async code which just isn't going to be possible so there is an opportunity here to simplify the code as we go.
from the execution_call.dart file.
This is probably more of what I'm used to but I do find the functional approach to the guard method somewhat cludgey.
With the current approach we have:
if the guard method simply threw then we could have this: