Implement trapdoor - atomic notifier #7997
Open
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Trapdoor
was originally implemented by @AlexHentschel (PR).Most of our workqueues currently use the
engine.Notifier
to synchronize producers and consumers. This works well in most cases, but has a subtle limitation that can cause inefficient use of workers in some cases. See comments in thenotifier.go
below for details. tl;dr when multiple workers are waiting and then multiple producers signal new work is available, some of the signals may be dropped, leaving a subset of the workers to handle all the work while others remain idle.Trapdoor
solves this by using async.Cond
to ensure that one signal is emitted for each call toActivate()
. This means that if there are waiting workers, one worker will be woken up for each call toActivate()
The current implementation uses a different API then
engine.Notify
. I think it might be useful for them both to implement the same interface, allowing for developers to choose the implementation that's needed for their use case. Notify may drop signals, but has no locks and is thus light weight. Trapdoor ensures no signals are dropped, but requires a mutex.