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

Multiple channels publish #41

Closed
aleksraiden opened this issue Nov 8, 2015 · 6 comments
Closed

Multiple channels publish #41

aleksraiden opened this issue Nov 8, 2015 · 6 comments

Comments

@aleksraiden
Copy link

For example:

command = {
        "method": "publish",
        "params": {"channels": ['channelA', 'channelB', 'channelC'], "data": {"input": "xxx"}}
}

One message published to many channels at once. For many scenario this dramaticly save traffic and performance (and at client-side too)

E.g. I have rss news server with 100 feed. Any user can subscribe to any feed or array of feeds. One case - each feed has own channel, server push message per channel. But if i can read 50 feed, at client we have 50 subscribers. In other case, server fetch actual user subscriptions and publish one message for all users, who have subscription.

@FZambia
Copy link
Member

FZambia commented Nov 8, 2015

Just thought how to implement this - there are several barriers. Every channel has its own options defined over namespaces. And every message sent has unique id and channel name. So at server side we have to anyway iterate over all channels and create message for each of them, apply namespace rules and finally publish into the wire. Also what if there will be an error publishing into one of those channels - how can Centrifugo return a response for this?

When using current implementation to publish into multiple channels there are no problems described above:

command = [
    {"method": "publish", "params": {"channel": "channelA", "data": {"input": "xxx"}},
    {"method": "publish", "params": {"channel": "channelB", "data": {"input": "xxx"}},
    {"method": "publish", "params": {"channel": "channelC", "data": {"input": "xxx"}},
]

And Centrifugo just returns 3 unique response objects for each publish command in request.

So the only real benefit here is traffic and a better looking publish code, due to the logic for each channel performance gain will most probably be minimal.

@aleksraiden
Copy link
Author

Maybe only for Redis lpush publish interface (without any responce)? If data payload has some size, and number of channels - we have very high overhead to data transfer (and we need more logic at publish script too) for publish.

Second idea - redis has binary-safe string, gzip/deflate data for publish?

@FZambia
Copy link
Member

FZambia commented Nov 8, 2015

Yes, it seems reasonable for use this with Redis API only. And maybe it's better to make this as new command and call method as something like publish_many (or just broadcast) to prevent breaking semantics of current publish command.

@aleksraiden
Copy link
Author

Yeah, good idea! Broadcast command sounds good!

@FZambia
Copy link
Member

FZambia commented Nov 10, 2015

done in efc52ad, it can be used over HTTP API too.

from cent.core import Client
client = Client("http://localhost:8000", "secret")
params = {"channels": ["public:test", "public:chat"], "data": {"input": "hello"}}
client.add("broadcast", params)
client.send()

It will publish data into channels until first error occurres. This error then set as response error and publishing stops. In case of using Redis API queue error will be logged. There is no currently mechanism on API client side to determine channels to which publishing was successful in case of error. Maybe I will add this as response body for publish and broadcast commands later.

@FZambia
Copy link
Member

FZambia commented Nov 29, 2015

This will be released in v1.2.0 and I'll also update docs

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

No branches or pull requests

2 participants