-
Notifications
You must be signed in to change notification settings - Fork 58
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
chore: supporting parallel libwaku requests #3273
Closed
Closed
Changes from all commits
Commits
Show all changes
8 commits
Select commit
Hold shift + click to select a range
be4450f
adding temporary debug log
gabrielmer 06c0ed0
using Channel
gabrielmer 263a660
Revert "using Channel"
gabrielmer 1d4c297
adding lock
gabrielmer 57951b2
removing debug log
gabrielmer 89f4a6f
releasing lock on errors
gabrielmer a83bdf3
adding comment
gabrielmer 5a106f7
improving comment
gabrielmer File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
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.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what happens with this lock during the
return err...
below?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why is the lock even here? channels are mpmc, you should not need a lock..
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a
ChannelSPSCSingle
channel fromtaskpools
. According to comments in its code, it can only buffer a single element. We observed the following behavior: When you try to calltrySend
more than once without having received any pending value on the other end of the channel,trySend
will return false. With this lock we wait until the other end receives the value.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I do wonder if we should instead use nim's builtin
Channel
instead ofChannelSPSCSingle
. I just saw that it has asend
that is blocking, as well as allowing to specify a max number of items in its buffer... 🤔There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes! So I first tried to move it to a
Channel
and had race conditions, not because of theChannel
itself but because of how we designed the mechanism of sending signals between threads. It is designed in such a way that assumes that a signal won't be sent if we have a pending request.I first wanted to try if we could have it working without redesigning too much. Given that the design already assumed there won't be concurrent requests to the channel and the only way for it to work was adding a lock, then
ChannelSPSCSingle
worked perfectly too so I switched back to it.After attempting to add a lock to the existing code, it resolved all the race conditions and performed really well - the only period it is locked is between the time a request is received to the moment it starts getting processed, but multiple requests can be processed in parallel.
I actually commented @Ivansete-status that we could refactor and redesign the mechanism of sending signals between threads to work without assuming that requests come one at a time but the current version performed so well that it seems to be an optimization that we can take care of if we see that this becomes a bottleneck.
Not sure if it makes sense, lmk if that's not the case :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"starts getting processed" in the loose sense of the term here, ie if the processing thread is running a synchronous computation that takes a while, it will not be removing things from the queue so all the other requests will form a line - the only "parallel" processing you get is what
async
gives you and these requests might end up getting blocked. This is probably worth documenting at least and it is what an MP queue would solve.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
True! But isn't that the case also with a MP queue? in the sense that if there's a sync operation in the processing thread that takes lots of computation, the queue will start getting filled with requests too.
The MP queue helps us add elements to the queue concurrently, but the actual execution of the requests should be the same in both cases right? or maybe I'm missing something?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree that we should document this! It's clear that a MP queue is a better design and we should not forget about it, this PR is only based on the fact that this solution works really well without the need of rearchitecting the logic of signaling between threads - so we can continue focusing on developing/fixing things critical for the integration of nwaku into Status Desktop and then optimize if needed
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the queue will hold the work but the thread that places the work on the queue can move on - with the lock, it will instead be blocked until the receiver has removed the item.
the "usual" way to do mp*c queues is to bound them to a fixed number of items and have a policy (block/drop) for what to do when the consumer is too slow - but when there's only one spot in the queue the blocking unnecessarily happens during short bursts even if the average production is lower than the capacity of the consumer.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh makes sense! Didn't think about that!
So 100% let's take care of it now - it can have a greater performance impact than what I envisioned.
Will close this PR and work on a MP*C solution.
Thanks so much for the help!