-
Notifications
You must be signed in to change notification settings - Fork 594
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
Pool workers to handle incoming deliveries, ACKs etc. #906
Comments
Note that at some point in the past we have had a dispatch pool per connection. I don't have an issue where this has been changed right now but the reasoning was to improve concurrency for some workloads. We expected that it would be problematic for high channel churn workloads but those workloads are problematic in many other ways. Channels are not meant to be very short lived. |
Completely understand. In that case, this might be totally unnecessary, but at least it's food for thought :) |
Also remember that since PR #878 you can share the channel from multiple threads, so opening / closing channels should also be needed less than before. @stebet Do you have any data that shows where we spend how much time? (Just curious) |
There is still the part about publish acknowledgments that are not thread safe yet. But I agree the documentation could be updated to reflect it more correctly. |
Not recent data no. I'll take a look at getting up to speed soon. Have been busy with a bunch of other projects recently, but I haven't forgotten you guys :) |
Closing due to lack of activity and my wish to get as many issues closed prior to the v7 release. |
After reading through a few issues (#876, #874) and doing some profiling I think I've found what the underlying issue is. Would love to get input from @danielmarbach, @bollhals and @bording on this.
Creating a new IModel, currently requires creating a new ConsumerDispatcher, which creates a WorkPool to handle incoming delivers, ACKs etc. This is all backed by a Channel and a Task that reads from that channel and executes it. The problem is, every time a new IModel is created, that means a new Task is created, which requires scheduling, which doesn't happen immediately, especielly under high churn. This effectively also makes it pretty expensive to both create and dispose of an IModel instance. You can easily see this by profiling a program that does nothing more than create and dispose a lot of IModel instances in the latest versions.
I think it would be very beneficial to keep a pool of WorkPool-like worker tasks on the Connection itself, which could be grabbed in the IConsumerDispatchers and those could then be handed the Work items to execute when these take place instead of scheduling a new Task for every model. The new concurrent processing configuration by @danielmarbach might need a little extra thought to handle parallel processing of deliveries per IModel using a shared pool, but if the Semaphores are still kept on the dispatchers which are per model, and those in turn decide how many tasks in parallel to hand over to the shared worker pool, I think that should still work fine.
So basically I'm proposing something like this:
This makes sense in my head at least, and could also increase throughput for high-churn scenarios.
The text was updated successfully, but these errors were encountered: