Closed GoogleCodeExporter closed 8 years ago
Indeed, the exception management can be problematic the way it is designed
right now. I'll see what I can do and I'll let you know every shortly when it
is fixed. Thanks for your report!
As for the difference between the LIST and QUEUE modes (see javadoc for
javapns.notification.transmission. NotificationThread.MODE), it depends on how
your software generates notifications... If your software has a known list of
notifications to push in one batch, the LIST mode would be the preferred way to
go because the library will open connections, push your notifications as fast
as possible, and close the connections. If on the other hand your software has
random single notifications to push (such as when you need to notify a specific
user about something), then using the QUEUE mode ensures that you won't be
constantly opening and closing connections for single notifications (which is
something that Apple warns against in their documentation).
Original comment by sype...@gmail.com
on 9 Nov 2011 at 8:24
Ok, I have completely revised the way exceptions are managed and propagated.
Now, communication and keystore problems will throw CommunicationException and
KeystoreException that will propagate out of the library. Other exceptions
that are specific to individual push notifications will continue to be noted
passively in PushedNotification objects so not to disrupt other notifications
being pushed.
Now, for NotificationThreads, this is a little more tricky. Individual threads
can experience CommunicationException and KeystoreExceptions, but since they're
running asynchronously from your own code, there needs to be a way to be aware
of those critical exceptions, both at the individual thread level and at the
thread coordination level. Thus, the way I've designed it today is that any
NotificationThread that experiences a critical exception will do two things:
memorize it for future examination (get it later using
notificationThread.getCriticalException()), and notify a
NotificationProgressListener if any is attached. Now, at the coordination
level, a new getCriticalExceptions() method has been added to
NotificationThreads to collect critical exceptions from all worker threads (if
any occurred). Finally, for easy usage of all this, a new variant to the
waitForAllThreads() method has been added with a boolean parameter indicating
whether to throw critical exceptions if any occur:
notificationThreads.waitForAllThreads(throwCriticalExceptions);
So, to summarize, invoke notificationThreads.waitForAllThreads(true) instead of
the original no-parameter method and an exception will be thrown if any thread
experienced a critical error such as CommunicationException or
KeystoreException.
All these changes are included in 2.1 Beta 2 which you can get from SVN.
Please let me know if this solves the issue you raised.
Thank you!
Sylvain
Original comment by sype...@gmail.com
on 9 Nov 2011 at 11:04
Thanks for the quick reply Sylvain. I'll pull the latest and try it out and
let you know.
Pete
Original comment by petend...@gmail.com
on 10 Nov 2011 at 4:40
I just committed a new build, so if you want to try the very latest version,
you might want to download the version currently in the trunk.
The new build includes a much simpler way of using multithreading... just call
Push.payload(yourPayload, keystore, password, production, 3, yourDevices) to
start 3 coordinated threads to push your list of notifications. The method
automatically waits for threads to finish, so when it returns, it does contain
a list of all PushedNotifications (unless a critical exception was thrown of
course).
The latest build also includes a very easy way of creating a queue:
Push.queue(keystore, password, production, 1) .. where 1 is the number of
threads to create for the queue. This method returns a PushQueue object, whose
add(..) methods you can call to push notifications asynchronously over the
permanent connection(s) of the queue.
Btw, your original code generated three malformed device tokens which the
library should prevent you from using...
Hey, are you the developer that met with Renaud a few days ago? :)
Original comment by sype...@gmail.com
on 11 Nov 2011 at 3:35
OK, I liked the simplicity of the new call that you documented in your last
comment. I tried the following from behind our corporate firewall:
List<PushedNotification> notifications =
Push.payload(payload,"C:\\PushCertificates.p12","abcd",false,1,deviceList)
The call appears to hang and not come back.
However, when I tried Push.payloads(....), that did appropriately throw the
CommunicationException. But I prefer the call that is hanging now because it
lets me specify a number of concurrent threads to execute.
Thoughts?
Original comment by petend...@gmail.com
on 14 Nov 2011 at 11:13
Could you provide a stack trace for the thread that is hanging, so that I can
understand where the code is blocked? Thank you!
Original comment by sype...@gmail.com
on 14 Nov 2011 at 11:28
This is odd. The thread that is started marked "Thread [JavaPNS grouped
notification thread in LIST mode]" ends after what is probably the amount of
time it needs to wait for the socket ConnectionException to be thrown, but
control doesn't seem to be passed back to my program. No exception is thrown,
nor does control come back to the calling program at all.
Hopefully that helps you narrow it down a bit more.
Original comment by petend...@gmail.com
on 15 Nov 2011 at 3:45
Hi. It would be helpful to have stack traces (dump) for all active threads, as
well as a complete copy of the log output (debug mode enabled). Without that,
it is difficult to understand what is going on and I can't help much.
In your test, how many devices do you have in your list and how many threads
are you creating?
Needed:
1) stack traces (dump) for all active threads
2) copy of the log output
Original comment by sype...@gmail.com
on 15 Nov 2011 at 4:10
Wait, I think I found what the problem is. I'll prepare a fix and get back to
you.
Original comment by sype...@gmail.com
on 15 Nov 2011 at 4:34
Original comment by sype...@gmail.com
on 15 Nov 2011 at 4:34
Ok, I found and fixed the problem. The cause was that in very recent builds,
the NotificationThread class was changed from a Thread to a Runnable, but the
actual underlying Thread objects created were not properly linked to their
ThreadGroup (the parent NotificationThreads object). Consequently, when the
worker threads finished working, they would not notify the parent
NotificationThreads because they didn't know about it.
The fix is in revision 310 (JavaPNS 2.1 Beta 2.005) which you can download
right now.
Original comment by sype...@gmail.com
on 15 Nov 2011 at 4:49
Yes, I just downloaded the latest from SVN and now Push.payload(...) that I
wanted to use behaves the same as NotificationThread's waitForAllThreads(true)
in that they return control to the calling program, throwing the expected
Exception.
Thanks for your help.
Original comment by petend...@gmail.com
on 15 Nov 2011 at 5:32
Outstanding! Thanks!
Original comment by sype...@gmail.com
on 15 Nov 2011 at 6:42
What do you suggest us to call when it is running in QUEUE Mode ?
I see the catch block in runQueue method
} catch (KeystoreException e) {
this.exception = e;
if (listener != null) listener.eventCriticalException(this, e);
} catch (CommunicationException e) {
this.exception = e;
if (listener != null) listener.eventCriticalException(this, e);
}
What happens when a CommunicationException or KeystoreException exception is
occured, it simply calls the Listener's method. When this thread will again
start processing the messages ? I see when this happens, it will never comeback
to runQueue method. When you call NotificationThreads.add method you are adding
messages to all the threads irrespective it is running or not. This could endup
in accumulating messages on a NotificationThread which has
communicationException and it is not running. This lead to OutOfMemory in my
case.
Please suggest what needs to be done here.
Original comment by dsreddy...@gmail.com
on 7 Jan 2014 at 2:48
Original issue reported on code.google.com by
petend...@gmail.com
on 9 Nov 2011 at 6:09