javagoogle-app-engineapple-push-notificationsjavapns

Can JavaPNS queue somehow be used in GAE? What are ways to batch APN payloads?


I am looking for a way to batch my APN payloads and use JavaPNS to send them. GAE does not allow use of JavaPNS queue class (bummer - I loved it!). Throws an exception (which is expected due to restrictions how threads are handled in GAE):

Caused by: java.security.AccessControlException: access denied ("java.lang.RuntimePermission" "modifyThreadGroup")
    at java.security.AccessControlContext.checkPermission(AccessControlContext.java:375)
    at java.security.AccessController.checkPermission(AccessController.java:565)
    at java.lang.SecurityManager.checkPermission(SecurityManager.java:549)
    at com.google.apphosting.runtime.security.CustomSecurityManager.checkPermission(CustomSecurityManager.java:56)
    at com.google.apphosting.runtime.security.CustomSecurityManager.checkAccess(CustomSecurityManager.java:131)
    at java.lang.ThreadGroup.checkAccess(ThreadGroup.java:315)
    at java.lang.ThreadGroup.checkParentAccess(ThreadGroup.java:135)
    at java.lang.ThreadGroup.<init>(ThreadGroup.java:117)
    at java.lang.ThreadGroup.<init>(ThreadGroup.java:96)
    at javapns.notification.transmission.NotificationThreads.<init>(NotificationThreads.java:150)
    at javapns.Push.queue(Push.java:234)
    ...

So what are my options? TaskQueue and pull queues sound promising but that would require backend application type and that makes it more expensive. Is it possible to create multiple producers, one consumer model in GAE servlet based application?


Solution

  • You can use Google Cloud Platform. It was written for GAE, it integrates with JavaPNs and it implements its own queues.

    You use our framework classes to interact with the deployed backend as if it was local to the device. We incorporated our recent work to deliver scalable, reliable push notifications to thousands of iOS devices via the Apple Push Notification Service.

    Connection pooling with backend instances and pull queues

    If you have a popular application you can quickly end up generating a large number of push notifications - even after a single event.

    For both performance reasons, and should avoid opening a large number of secure connections to APNS, but rather simply hold a few connections open and funnel any push notifications your applications generate through those. This approach is commonly called Connection Pooling.

    Fortunately, App Engine provides the building blocks for scalable connection pooling. Resident backend instances are long running App Engine containers that can be used to as workers to hold open APNS notifications for sending notifications. These workers can then monitor a pull queue that can signal to the workers when a notification should be sent. When an event occurs in another component of your application that should trigger a push notification (say an action triggered by your mobile API in a frontend instance), other components of your application can simply enqueue a task on the pull queue.

    Each worker can then periodically read from a pull queue to see if any notifications need to be sent by the application, and if there are, lease a block of them, send them via the previously established APNS connection, and delete them.

    Connecting to APNS

    While you can use App Engine’s outbound sockets support to talk to APNS from Java or Python directly, popular 3rd party libraries such as JavaPNS also work well, and often provide a cleaner higher level interface for sending notifications.