mblawrence / javapns

Automatically exported from code.google.com/p/javapns
0 stars 0 forks source link

Performance problem #180

Open GoogleCodeExporter opened 8 years ago

GoogleCodeExporter commented 8 years ago
What steps will reproduce the problem?
1.
2.
3.

What is the expected output? What do you see instead?

What version of the product are you using? On what operating system?
Latest JavaPNS 2.2
OS Doesn't matter. Result is same on Linux and MacOSX

Please provide any additional information below.
We are using JavaPNS library for sending push notifications. But we are 
complaining about its performance. We could send a pns in 6 seconds. So we are 
using 150 threads for sending 25pns/sec. Is it normal for JavaPNS to push a pns 
in 6 seconds?

Our Server is in DMZ and firewall configuration is done for Apple IP/ports.

Original issue reported on code.google.com by erc...@gmail.com on 25 Apr 2013 at 9:25

GoogleCodeExporter commented 8 years ago
When i debug the code i figured out that javapns is creating a new connection 
for every push notification as below. And every notification is pushed about in 
6 seconds.

I think creating connection is the taking major time of 6 second. Is it 
possible to send notifications in one connection?

6564 [main] DEBUG javapns.notification.Payload  - Adding alert [Deneme 1]
6573 [main] DEBUG javapns.communication.ConnectionToAppleServer  - Creating 
SSLSocketFactory
6583 [main] DEBUG javapns.communication.ConnectionToAppleServer  - Creating 
SSLSocket to gateway.sandbox.push.apple.com:2195
6737 [main] DEBUG javapns.notification.PushNotificationManager  - Initialized 
Connection to Host: [gateway.sandbox.push.apple.com] Port: [2195]: 
a383118[SSL_NULL_WITH_NULL_NULL: 
Socket[addr=gateway.sandbox.push.apple.com/17.172.233.66,port=2195,localport=537
49]]
6738 [main] DEBUG javapns.notification.PushNotificationManager  - Building Raw 
message from deviceToken and payload
6738 [main] DEBUG javapns.notification.PushNotificationManager  - Built raw 
message ID 1 of total length 73
6738 [main] DEBUG javapns.notification.PushNotificationManager  - Attempting to 
send notification: {"aps":{"alert":"Deneme 1"}}
6738 [main] DEBUG javapns.notification.PushNotificationManager  -   to device: 
cd72082130fde7961d185bf55d3b78207d036cde9f32478ec877ad5708386805
7253 [main] DEBUG javapns.notification.PushNotificationManager  - Flushing
7253 [main] DEBUG javapns.notification.PushNotificationManager  - At this 
point, the entire 73-bytes message has been streamed out successfully through 
the SSL connection
7253 [main] DEBUG javapns.notification.PushNotificationManager  - Notification 
sent on first attempt
7253 [main] DEBUG javapns.notification.PushNotificationManager  - Reading 
responses
12254 [main] DEBUG javapns.notification.PushNotificationManager  - Closing 
connection
12254 [main] DEBUG javapns.notification.Payload  - Adding alert [Deneme 2]
12258 [main] DEBUG javapns.communication.ConnectionToAppleServer  - Creating 
SSLSocketFactory
12262 [main] DEBUG javapns.communication.ConnectionToAppleServer  - Creating 
SSLSocket to gateway.sandbox.push.apple.com:2195
12414 [main] DEBUG javapns.notification.PushNotificationManager  - Initialized 
Connection to Host: [gateway.sandbox.push.apple.com] Port: [2195]: 
5097d026[SSL_NULL_WITH_NULL_NULL: 
Socket[addr=gateway.sandbox.push.apple.com/17.172.233.66,port=2195,localport=537
50]]
12415 [main] DEBUG javapns.notification.PushNotificationManager  - Building Raw 
message from deviceToken and payload
12415 [main] DEBUG javapns.notification.PushNotificationManager  - Built raw 
message ID 1 of total length 73
12415 [main] DEBUG javapns.notification.PushNotificationManager  - Attempting 
to send notification: {"aps":{"alert":"Deneme 2"}}
12415 [main] DEBUG javapns.notification.PushNotificationManager  -   to device: 
cd72082130fde7961d185bf55d3b78207d036cde9f32478ec877ad5708386805
12923 [main] DEBUG javapns.notification.PushNotificationManager  - Flushing
12923 [main] DEBUG javapns.notification.PushNotificationManager  - At this 
point, the entire 73-bytes message has been streamed out successfully through 
the SSL connection
12923 [main] DEBUG javapns.notification.PushNotificationManager  - Notification 
sent on first attempt
12923 [main] DEBUG javapns.notification.PushNotificationManager  - Reading 
responses
17924 [main] DEBUG javapns.notification.PushNotificationManager  - Closing 
connection
17925 [main] DEBUG javapns.notification.Payload  - Adding alert [Deneme 3]
17928 [main] DEBUG javapns.communication.ConnectionToAppleServer  - Creating 
SSLSocketFactory
17932 [main] DEBUG javapns.communication.ConnectionToAppleServer  - Creating 
SSLSocket to gateway.sandbox.push.apple.com:2195
18084 [main] DEBUG javapns.notification.PushNotificationManager  - Initialized 
Connection to Host: [gateway.sandbox.push.apple.com] Port: [2195]: 
1ee29820[SSL_NULL_WITH_NULL_NULL: 
Socket[addr=gateway.sandbox.push.apple.com/17.172.233.66,port=2195,localport=537
51]]
18084 [main] DEBUG javapns.notification.PushNotificationManager  - Building Raw 
message from deviceToken and payload
18084 [main] DEBUG javapns.notification.PushNotificationManager  - Built raw 
message ID 1 of total length 73
18084 [main] DEBUG javapns.notification.PushNotificationManager  - Attempting 
to send notification: {"aps":{"alert":"Deneme 3"}}
18084 [main] DEBUG javapns.notification.PushNotificationManager  -   to device: 
cd72082130fde7961d185bf55d3b78207d036cde9f32478ec877ad5708386805
18594 [main] DEBUG javapns.notification.PushNotificationManager  - Flushing
18594 [main] DEBUG javapns.notification.PushNotificationManager  - At this 
point, the entire 73-bytes message has been streamed out successfully through 
the SSL connection
18594 [main] DEBUG javapns.notification.PushNotificationManager  - Notification 
sent on first attempt
18594 [main] DEBUG javapns.notification.PushNotificationManager  - Reading 
responses
23595 [main] DEBUG javapns.notification.PushNotificationManager  - Closing 
connection

Original comment by erc...@gmail.com on 25 Apr 2013 at 12:52

GoogleCodeExporter commented 8 years ago
Hi, are you using Push.queue or first setting up your PushNotificationManager 
manually using:

PushNotificationManager pushManager = new PushNotificationManager();
pushManager.initializeConnection(customServer);

Original comment by j...@jameslow.com on 29 Apr 2013 at 1:26

GoogleCodeExporter commented 8 years ago
Hi. 
I am using PushNotificationManager to send notifications as you mentioned and 
the performance is very well now. In previous implementation i used 
Push.alert/Push.complex and it tooks 6 seconds per notification because the ssl 
connection is closed always in 5 seconds.

Thank you very much. 

Original comment by erc...@gmail.com on 8 May 2013 at 7:39

GoogleCodeExporter commented 8 years ago
Please provide the code you wrote that invokes JavaPNS...

But if you are repeatedly invoking a method of the Push class to loop over your 
payloads, the delay you are seeing is pretty normal.  The 5 seconds delay is 
unfortunately required before closing a socket to make sure that all response 
packets have been received (upon experience, APNS causes some delays from time 
to time and it was possible to loose packets if closing the connection too 
early).

So, you should not be repeatedly calling JavaPNS to send your payloads.  
Instead, you should be providing your entire list of payloads and/or devices 
and to a single method of the Push class to take care of the batch transmission 
for you.  JavaPNS will handle all the transmission details and make very 
efficient use of the sockets it needs to send your notifications.

Original comment by sype...@gmail.com on 8 May 2013 at 9:14

GoogleCodeExporter commented 8 years ago
Here is my code:

...
PushNotificationManager pushManager = new PushNotificationManager();
AppleNotificationServer server;
try {
   ...
   server = new AppleNotificationServerBasicImpl(ServiceProxy.getInstance()
                    .getServletRealPath() + "WEB-INF/classes/" +   apns.getKeyStore(), apns.getPassword(), apns.isProduction());
   pushManager.initializeConnection(server);
   notifications.setMaxRetained(notificationList.size());
   ...
   Payload payload = PushNotificationPayload.combined(pnsMessage, -1, "default");
   PushedNotification notification = pushManager.sendNotification(Devices.asDevices(sentNtf.getInstalledApp().getPnsToken()).get(0), payload, false);
   ...
catch (KeystoreException e) {
   e.printStackTrace();
}catch (CommunicationException e) {
   e.printStackTrace();
}finally {
   try {
      pushManager.stopConnection();
       } catch (Exception e) {
       e.printStackTrace();
       }
}

Original comment by erc...@gmail.com on 9 May 2013 at 6:23

GoogleCodeExporter commented 8 years ago
That code seems to be pushing a single notification at a time...  If you have 
multiple notifications to push, you should push them altogether in one batch, 
to avoid the per-connection delay I mentioned before.

Also, your code seems overly complex... I suggest you take a look at the 
documentation, and more specifically at the Push class which does everything 
your code does, but requires only a single line of code from you.

Original comment by sype...@gmail.com on 23 May 2013 at 7:53

GoogleCodeExporter commented 8 years ago
Hi we are facing exact similar issue. you suggested:
"If you have multiple notifications to push, you should push them altogether in 
one batch, to avoid the per-connection delay I mentioned before."

It makes sense if same message is being pushed to multiple devices to list out 
all devices and send notification once Using Push.payload().
What if payload messages varies per device, we will have to use this multiple 
times isn't it? Is there a better way to do it?
PushedNotification notification = pushManager.sendNotification(List<Device>, 
payload, false);

Original comment by mtha...@apostek.com on 24 May 2013 at 7:38

GoogleCodeExporter commented 8 years ago
Also if i use PushQueue which is async what is the best way to OPT Out invalid 
token? We may not use instant PushNotification.isSuccessful() check like we do 
for Push.payload().

Original comment by mtha...@apostek.com on 24 May 2013 at 9:09

GoogleCodeExporter commented 8 years ago
Regarding batch pushing, the Push class provides methods for pushing multiple 
pairs of payload+device.  I suggest you take a look at the "Basic Push 
Notification" wiki page and look for methods that accept a "payloadDevicePairs" 
parameter.  The possible values for that parameter are described on that same 
wiki page.

Regarding the PushQueue, there is currently no way to wait for the definitive 
result of a particular notification.  Since the queue works asynchronously, and 
that failures may result from error-response packets which may come at any 
time, there is currently no reliable way of getting that definitive result.  I 
suspect though that you were trying to use a Queue to work around the 
per-notification delay you were experiencing, but if you push your 
notifications in batches, you should no longer have performance issues.

Original comment by sype...@gmail.com on 25 May 2013 at 12:16

GoogleCodeExporter commented 8 years ago
Thanks for confirming that PushQueue may delay the response packets. 
Could you please tell me what should be the max( or may be the best 
performance) limit on PayloadPerDevice list size?

Original comment by mtha...@apostek.com on 27 May 2013 at 9:23

GoogleCodeExporter commented 8 years ago
May I suggest enhancing the Javapns Queue API such when an error occur an Event 
is triggered (in the queue listener). 
And if a user supplied a listener to the push queue it preform the event method 
QueueLister.onError(Payload p, Device d, Exception e).

I would do the same for a push notification that was successfully sent, thus 
user has the ability to track which item were sent without polling the 
Push-Queue

Original comment by meirda...@gmail.com on 17 Jun 2013 at 11:10

GoogleCodeExporter commented 8 years ago
I am using payload per device approach and that is working perfectly fine. Only 
Issue I faced is of performance for payload count more than 20. There I see a 
paradigm shoot in response time. Kindly suggest remedy to such thing. PS : I 
tried passing the thread count to Push.Payloads().. Still same. Please help me 
to understand such anomaly.

Original comment by compchap...@gmail.com on 4 Oct 2013 at 7:38

GoogleCodeExporter commented 8 years ago
has any one faced issue similar to the one mentioned above?

Original comment by compchap...@gmail.com on 24 Oct 2013 at 8:59

GoogleCodeExporter commented 8 years ago
Hi Folks,

My use case is also sending one notification to one device at a time. I am 
using push queue queue.add(payload, token) to send messages. I notice in 
runQueue() method in NotificationThread.java line 293, there is a 10 second 
sleep. 

I am wondering is the purpose of this sleep due to fact that 5 seconds delay is 
required before closing a socket mentioned in this thread earlier?

If that is the case, why is 10 seconds, instead of 5 seconds?

Also suppose there are 5 threads in the queue with 5 coming messages to send, 
and each message is added to a different thread, does this means when the 6th 
message come, the delay for the 6th message to be sent in worst case would be 
10 seconds?
 Is there any way to address this delay?

Thank you very much for valuable inputs in advance!

Original comment by wry.b...@gmail.com on 13 Jan 2015 at 5:06