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

Send notifications in batch rather than one-by-one #42

Closed
patrickdappollonio opened this issue Nov 19, 2013 · 5 comments
Closed

Send notifications in batch rather than one-by-one #42

patrickdappollonio opened this issue Nov 19, 2013 · 5 comments
Assignees
Milestone

Comments

@patrickdappollonio
Copy link

Hello!

I'm using uniqush 1.5.0 (and now 1.5.1) on a large-scale android app (sorry, but I can't provide the name :() and we sent almost 50 millions push notifications in a lapse of time of around 2 months.

The only problem I encountered with the app is that while GCM allows to send up to 1000 IDs at once, Uniqush just send them one by one. It will be great to check first if uniqush receives a request to send a notification to all registered devices and, rather than send them one-by-one, send them in batch of 1000 devices each time...

I'm not such a good programmer and I don't know Go lang either so I couldn't help updating the app :(

@ghost ghost assigned monnand Nov 19, 2013
@monnand
Copy link
Member

monnand commented Nov 19, 2013

@patrickdappollonio Thank you so much for your report! I'm so glad to see more users of uniqush! Even though I don't know the name of your app, I wish you the best of luck and every success in your business.

Right now, uniqush only uses multicast mechanism when you explicitly specifies multiple receivers. When you specify receivers, you can separate them with comma, or you can use wild card to send to all users whose name with certain pattern. I think this might be something like what you are talking about.

Here is an example of sending notifications to user1 and user2:

curl http://127.0.0.1:9898/push -d service=myservice -d subscriber="user1,user2" -d msg="Hello World"

Or, another way of doing it is to use wild card. The following command will send message to all subscribers whose name starts with usr:

curl http://127.0.0.1:9898/push -d service=myservice -d subscriber=usr* -d msg="Hello World"

I think this will work with GCM without too much problem. However, for APNS, it might be tricky because APNS does not support multicast natively. According to #40, uniqush may use large amount of memory (>3.75G) when you try to send messages to more than 500K iOS users concurrently.

I will try to fix the OOM error in #40 so that both of you will benefit from the fix.

There might be some advanced technique to be used here to use multicast more aggressively: for each request that uniqush receives, it will wait for a short period of time in hopes of receiving another request with same content but different subscriber (and send theses two messages using GCM's multicast.) This is basically the same idea of Nagle's algorithm. However, I may not add this feature in the recent release.

Again, thanks for using uniqush! Please let me know if you have any questions!

@patrickdappollonio
Copy link
Author

Thank you for your reply!

Currently, we're pushing notifications almost each day to more than 6 million active users. We're using the * wildcard to send those notifications and I thought that uniqush wasn't using the GCM option to pass 1000 suscribers each time and instead sending all notifications one-by-one (I thought that because the log that appears when you submit the notification goes one by one, silly me!)

So, I wasn't talking about the usage between my API and Uniqush local server, I was talking what happens under the hood when you send a notification to all users, if uniqush was smart enough to send those notifications from uniqush local server to GCM in batches of 1000 registration IDs.

Regarding memory consumption, when we send a notification to all our Android devices, uniqush uses around 2.3G of memory (my current RAM config is 2x RAM 8192 MB DDR3) and I never encountered any troubles like app being force-closed or memory issues even in large-scale.

@monnand
Copy link
Member

monnand commented Nov 19, 2013

@patrickdappollonio I just briefly reviewed the code. Both of us are correct: Uniqush is using GCM's multicast when you use wild card; and it is producing one log entry per device.

Since each device may fail independently, a result of a multicast operation may contains both success and bad pushes. I chose an easy (and sort of consistent) way to produce the push result: One device will produce one log entry unless uniqush wants to resend the message (When the push service provider has a temporal error.)

(I didn't run the program to check if it actually used the multicast. But according to the code, it should --- unless some buggy code there. I will confirm this tomorrow by actually running the program.)

@patrickdappollonio
Copy link
Author

Great! Thank you so much. Such a great piece of software. If you need beta testing, just tell me :D

@monnand
Copy link
Member

monnand commented Nov 19, 2013

@patrickdappollonio You're welcome! I'm so glad to see that uniqush is used in such a large scale system.

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