question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Allow dynamic lookup of APNS authentication keys via topics

See original GitHub issue

We have built a platform that provides many applications with a variety of services. For APNS connections we’ve been using Pushy with great results.

Since we are a platform with constant uptime, new applications are registered dynamically. Any application that needs to pass information to APNS will provide us with the required keys and topics during registration. This brings me to the configuration challenge we have with Pushy.

Problem Outline


Pushy, currently, requires that all topics are registered with their associated token before a message can be sent to that topic. For single application systems, or even multiple application systems with a finite set of applications, this is a simple and practical approach. For our platform this configuration requirement is a bit of a nuisance and doesn’t make the best use of resources.

Here’s an example explaining some of the problems. First, an application is registered with our platform and APNS topics and keys are provided. The application is used for testing for a few times then left idle for a period of time (say until the next time testing is done). With Pushy currently we must pre-register the topics and keys for the new application so they are ready when APNS communication is attempted; this could be registered “eagerly” when the application is registered or “lazily” when the first attempt to communicate with APNS about the specified topic is made. If/when the application is unregistered we can unregister the topics and keys from Pushy. So far, no problem, but when the application is left idle and unused it’s now consuming resources (memory for keys, topics & CPU as the ApnsRegistry grows in size). As the number of applications registered grows so does our resource usage. This is essentially the “memory leak via infinite caching” problem.

The only solution, currently, is to test the ApnsRegistry to see if the topic is registered then call into Pushy normally; essentially lazy registration. Unfortunately, nothing currently exists to handle the case of unregistering topics/tokens. There is no way to introspect the ApnsRegistry and do cache pruning based on LRU or other methods.

Proposed Solution


Now that the problem description is, hopefully, outlined well here’s my suggested solution (this is built upon the code in #404)

Replace ApnsRegistry in the ApnsClientHandler with a simple interface for locating an ApnsKey for a specific topic; e.g. ApnsKeyLocator. That coupled with some method of providing a specific implementation of ApnsKeyLocator to the ApnsClientHandler would allow users to match implementations to their usage.

I can think of 3 implementations people might need:

  • ApnsKeyRegistry: A synchronized locator that can be shared between handlers; the registry name implies pre-registered keys. (i.e. the current method)
  • ApnsConcurrentKeyRegistry: A locator that manages one ApnsKeyRegistry per handler (eschewing locking). (i.e. the method proposed)
  • ApnsOnDemandLocator: A locator that dynamically looks up keys as they are requested. An implementation based on the Guava LoadingCache is imagined.

To be implemented most flexibly you would need two interfaces:

  • ApnsKeyLocator: The interface ApnsClientHandler uses to locate keys for specific topics.
  • ApnsKeyLocatorFactory: The interface provided to ApnsClient used to create a ApnsKeyLocator for each new handler.

Proposed interfaces for the above:

interface ApnsKeyLocator {
  /*
    Looks up an ApnsKey for a given topic.
    
    Providing the ApnsClientHandler during locating allows implementations to 
    optimize based on the individual handler (e.g. for concurrency).
   */
  ApnsKey locate(ApnsClientHandler handler, String topic);
}

interface ApnsKeyLocatorFactory {
  /*
    Creates, shares or recycles an ApnsKeyLocator for the handler.

    Not sure these parameters are necessary, or even useful, for actual implementations
    but erring on the side of flexibility and providing as much context as possible.
   */
  ApnsKeyLocator create(ApnsClient client, ApnsClientHandler handler);
}

For “compatibility” you could make ApnsClient which would work with nothing but ApnsKeyLocatorFactory and be the most flexible implementation. A SimpleApnsClient would manage an internal ApnsKeyRegistery (imagined above); providing all the same key registration methods ApnsClient currently does.

Issue Analytics

  • State:closed
  • Created 7 years ago
  • Comments:11 (7 by maintainers)

github_iconTop GitHub Comments

1reaction
jchamberscommented, Jan 6, 2017

Much appreciated. Let’s get the connection pooling stuff settled out first, though, just in case that dredges up some shocking architectural revelations that would make things difficult here.

0reactions
jchamberscommented, Apr 15, 2017

Sadly, I think we have to shelve this for now. It turns out that the intended behavior is “one team per connection.” I think that means that the whole registry pattern is basically crazy at this point, and we should plan on just binding a single key to a connection.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Sending Notification Requests to APNs - Apple Developer
Upon receiving your server's POST request, APNs validates the request using either the provided authentication token or your server's certificate. If validation ......
Read more >
iOS: Push Notification Token Setup - Support : Knowledge Base
iOS: Push Notification Token Setup · Fill out a name for your key in the "Key Name" field and enable APNs by ticking...
Read more >
Set up a Firebase Cloud Messaging client app on Apple ...
Upload your APNs authentication key · Inside your project in the Firebase console, select the gear icon, select Project Settings, and then select...
Read more >
iOS Push Notifications | PubNub Docs
On the Admin Portal, go to the Mobile Push Notifications section from the Keys page. Click Upload Token File to upload your APNs...
Read more >
Applying Dynamically Generated Isolation Policies in SaaS ...
As part of adopting a multi-tenant software-as-a-service (SaaS) model, a key challenge is how to provide strong tenant isolation in a cost ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found