Skip to content
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

Publish batching in Redis Engine #84

Merged
merged 13 commits into from
Mar 23, 2016
Merged

Publish batching in Redis Engine #84

merged 13 commits into from
Mar 23, 2016

Conversation

FZambia
Copy link
Member

@FZambia FZambia commented Mar 22, 2016

As part of #59

@FZambia
Copy link
Member Author

FZambia commented Mar 22, 2016

To summarize things done in this pr:

Added pubRequest struct and pubCh to Redis Engine. Now every publish results in sending pubRequest to pubCh - and one goroutine reads from that channel, batches publish requests and sends to Redis (keeping publish engine method synchronous). Almost the same like @banks already did for managing subscriptions.

return resp, nil
}
wg.Add(1)
go func(channel Channel) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, this works but it feels off to me...

It's intentionally creating overhead and contention on the publish channel etc as well as spawning maybe thousands of goroutines. Perhaps that's not too bad in practice, but in theory it would be possible to do this much more efficiently if we had a real async API in our engine interface.

Maybe something for the future?

@FZambia
Copy link
Member Author

FZambia commented Mar 22, 2016

Actually that was not so simple because we don't call engine method directly from broadcastCmd - we call application's publish method which contains lot of helper logic.

But anyway I think I changed it in a way you suggested - not adding new engine method though but returning error channel from existing and added helper method to publish synchronously to Application.

Result is wonderful: broadcast now 2 times faster for 10000 channels than version with goroutines. So overall performance improvement for broadcast is about 11-12x

@banks
Copy link
Member

banks commented Mar 22, 2016

Great!

Will look at code again tomorrow but that just didn't look very efficient!

Thanks

On 22 Mar 2016, at 21:27, Alexandr Emelin [email protected] wrote:

Actually that was not so simple because we don't call engine method directly from broadcastCmd - we call application's publish method which contains lot of helper logic.

But anyway I think I changed it in a way you suggested - not adding new engine method though but returning error channel from existing and added helper method to publish synchronously to Application.

Result is wonderful: broadcast now 2 times faster for 10000 messages than version with goroutines.


You are receiving this because you were mentioned.
Reply to this email directly or view it on GitHub

adminChannel := app.config.AdminChannel
app.RUnlock()
return app.engine.publish(adminChannel, message, nil)
func (app *Application) enginePublish(chID ChannelID, message []byte, opts *publishOpts) error {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nitpick but that name is a little bit confusing. It's real purpose is a synchronous helper so maybe publishSync would be cleaner name?

Not a big deal if you disagree though.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agree, just deleted it

@banks
Copy link
Member

banks commented Mar 23, 2016

This looks great to me 👍

If I get a chance, I'll try it out, but don't wait if you are happy.

@FZambia
Copy link
Member Author

FZambia commented Mar 23, 2016

ok, thanks a lot for looking! I can't find something I can improve here at moment - so going to merge this then. This async publish method in engine opens a road to further optimizations maybe - i.e. something like async: true in publish command if user don't need to wait for publish result to speed up publish commands coming from single Redis queue for example. But let's discuss this later outside this pr.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants