public class PushManager<T extends ApnsPushNotification> extends Object implements ApnsConnectionListener<T>
Push managers manage connections to the APNs gateway and send notifications from their queue. Push managers are the main public-facing point of interaction with Pushy.
A push manager has two queues: the public queue through which callers add notifications to be sent, and a private,
internal "retry queue." Callers send push notifications by adding them to the push manager's public queue
(see getQueue()
). The push manager will take and notifications from the public queue as quickly
as it is able to do so, and will never put notifications back in the public queue. Callers are free to manipulate the
public queue however they see fit.
If, for any reason other than a permanent rejection, a notification could not be delivered, it will be returned to the push manager's internal retry queue. The push manager will always try to drain its retry queue before taking new notifications from the public queue.
A push manager can be shut down with or without a timeout, though shutting down without a timeout provides stronger guarantees with regard to the state of sent notifications. Regardless of whether a timeout is specified, push managers will stop taking notifications from the public queue as soon the shutdown process has started. Push managers shut down by asking all of their connections to shut down gracefully by sending a known-bad notification to the APNs gateway. The push manager will restore closed connections and keep trying to send notifications from its internal retry queue until either the queue is empty or the timeout expires. If the timeout expires while there are still open connections, all remaining connections are closed immediately.
When shutting down without a timeout, it is guaranteed that the push manager's internal retry queue will be empty and all sent notifications will have reached and been processed by the APNs gateway. Any notifications not rejected by the gateway by the time the shutdown process completes will have been accepted by the gateway (though no guarantees are made that they will ever be delivered to the destination device).
Callers may register listeners to handle notifications permanently rejected by the APNs gateway and to handle failed attempts to connect to the gateway.
When a notification is rejected by the APNs gateway, the rejection should be considered permanent and callers
should not try to resend the notification. When a connection fails, the push manager will report the failure to
registered listeners, but will continue trying to connect until shut down. Callers should shut down the push manager
in the event of a failure unlikely to be resolved by retrying the connection (the most common case is an
SSLHandshakeException
, which usually indicates a certificate problem of some kind).
getQueue()
Constructor and Description |
---|
PushManager(ApnsEnvironment environment,
SSLContext sslContext,
NioEventLoopGroup eventLoopGroup,
ExecutorService listenerExecutorService,
BlockingQueue<T> queue,
PushManagerConfiguration configuration,
String name)
Constructs a new
PushManager that operates in the given environment with the given SSL context and the
given number of parallel connections to APNs. |
Modifier and Type | Method and Description |
---|---|
String |
getName()
Returns the human-readable name of this push manager.
|
BlockingQueue<T> |
getQueue()
Returns the queue of messages to be sent to the APNs gateway.
|
void |
handleConnectionClosure(ApnsConnection<T> connection)
Indicates that the given connection has disconnected from the previously-connected APNs gateway and can no
longer send push notifications.
|
void |
handleConnectionClosure(FeedbackServiceConnection connection)
Indicates that the given connection has disconnected from the APNs feedback service and will no longer receive
expired tokens.
|
void |
handleConnectionFailure(ApnsConnection<T> connection,
Throwable cause)
Indicates that the given connection attempted to connect to an APNs gateway, but failed.
|
void |
handleConnectionFailure(FeedbackServiceConnection connection,
Throwable cause)
Indicates that the given connection attempted to connect to the APNs feedback service, but failed.
|
void |
handleConnectionSuccess(ApnsConnection<T> connection)
Indicates that the given connection successfully connected to an APNs gateway and is ready to send push
notifications.
|
void |
handleConnectionSuccess(FeedbackServiceConnection connection)
Indicates that the given connection successfully connected to the APNs feedback service and will receive expired
when they are sent by the feedback service.
|
void |
handleConnectionWritabilityChange(ApnsConnection<T> connection,
boolean writable)
Indicates that the given connection has changed its writability state.
|
void |
handleExpiredToken(FeedbackServiceConnection connection,
ExpiredToken token)
Indicates that the given connection received an expired token from the APNs feedback service.
|
void |
handleRejectedNotification(ApnsConnection<T> connection,
T rejectedNotification,
RejectedNotificationReason reason)
Indicates that a notification sent via the given connection was definitively rejected by the APNs gateway.
|
void |
handleUnprocessedNotifications(ApnsConnection<T> connection,
Collection<T> unprocessedNotifications)
Indicates that notifications that had previously been sent to an APNs gateway by the given connection were not
processed by the gateway and should be sent again later.
|
void |
handleWriteFailure(ApnsConnection<T> connection,
T notification,
Throwable cause)
Indicates that the given connection failed to send a push notification to an APNs gateway.
|
boolean |
isShutDown()
Indicates whether this push manager has been shut down (or is in the process of shutting down).
|
boolean |
isStarted()
Indicates whether this push manager has been started and not yet shut down.
|
void |
registerExpiredTokenListener(ExpiredTokenListener<? super T> listener)
Registers a listener for expired tokens received from the feedback service.
|
void |
registerFailedConnectionListener(FailedConnectionListener<? super T> listener)
Registers a listener for failed attempts to connect to the APNs gateway.
|
void |
registerRejectedNotificationListener(RejectedNotificationListener<? super T> listener)
Registers a listener for notifications rejected by APNs for specific reasons.
|
void |
requestExpiredTokens()
Begins an asynchronous attempt to get a list of expired tokens from the feedback service.
|
void |
shutdown()
Disconnects from APNs and gracefully shuts down all connections.
|
List<T> |
shutdown(long timeout)
Disconnects from the APNs and gracefully shuts down all connections.
|
void |
start()
Opens all connections to APNs and prepares to send push notifications.
|
boolean |
unregisterExpiredTokenListener(ExpiredTokenListener<? super T> listener)
Un-registers an expired token listener.
|
boolean |
unregisterFailedConnectionListener(FailedConnectionListener<? super T> listener)
Un-registers a connection failure listener.
|
boolean |
unregisterRejectedNotificationListener(RejectedNotificationListener<? super T> listener)
Un-registers a rejected notification listener.
|
public PushManager(ApnsEnvironment environment, SSLContext sslContext, NioEventLoopGroup eventLoopGroup, ExecutorService listenerExecutorService, BlockingQueue<T> queue, PushManagerConfiguration configuration, String name)
Constructs a new PushManager
that operates in the given environment with the given SSL context and the
given number of parallel connections to APNs. See
Best Practices for Managing Connections for additional information.
This constructor may take an event loop group as an argument. The push manager's event loop group will be
used for IO operations in all connections created by this push manager. If an event loop group is provided, the
caller is responsible for managing the lifecycle of the group and must shut it down after
shutting down this PushManager
.
This constructor may also take an ExecutorService
as an argument. The executor
service is used to dispatch notifications to registered listeners. If a non-null
executor service is
provided, callers must shut down the executor service after shutting down all
PushManager
instances that use that executor service.
environment
- the environment in which this PushManager
operates; must not be null
sslContext
- the SSL context in which APNs connections controlled by this PushManager
will operate;
must not be null
eventLoopGroup
- the event loop group this push manager should use for its connections to the APNs gateway and
feedback service; if null
, a new event loop group will be created and will be shut down automatically
when the push manager is shut down. If not null
, the caller must shut down the event
loop group after shutting down the push manager.listenerExecutorService
- the executor service this push manager should use to dispatch notifications to
registered listeners. If null
, a new single-thread executor service will be created and will be shut
down automatically with the push manager is shut down. If not null
, the caller must
shut down the executor service after shutting down the push manager.queue
- the queue to be used to pass new notifications to this push manager; if null
, the new push
manager will create its own queueconfiguration
- the set of configuration options to use for this push manager and the connections it
creates. The configuration object is copied and changes to the original object will not propagate to the push
manager after creation. Must not be null
.name
- a human-readable name for this push manager; if null
, a default name will be usedpublic void start()
Opens all connections to APNs and prepares to send push notifications. Note that enqueued push notifications will not be sent until this method is called.
Push managers may only be started once and cannot be reused after being shut down.
IllegalStateException
- if the push manager has already been started or has already been shut downpublic boolean isStarted()
true
if this push manager has been started and has not yet been shut down or false
otherwisepublic boolean isShutDown()
true
if this push manager has been shut down or is in the process of shutting down or
false
otherwisepublic void shutdown() throws InterruptedException
Disconnects from APNs and gracefully shuts down all connections. As soon as this method is called, the push
manager will stop taking notifications from the public queue. This method will block until the internal retry queue
has been emptied and until all connections have shut down gracefully. Calling this method is identical to calling
shutdown(long)
with a timeout of 0
.
By the time this method return normally, all notifications removed from the public queue are guaranteed to have been delivered to the APNs gateway and either accepted or rejected (i.e. the state of all sent notifications is known).
InterruptedException
- if interrupted while waiting for connections to close cleanlyIllegalStateException
- if this method is called before the push manager has been startedpublic List<T> shutdown(long timeout) throws InterruptedException
Disconnects from the APNs and gracefully shuts down all connections. As soon as this method is called, the push manager will stop taking notifications from the public queue. This method will wait until either the given timeout expires or until the internal retry queue has been emptied and connections have closed gracefully. If the timeout expires, the push manager will close all connections immediately.
This method returns the notifications that are still in the internal retry queue by the time this push manager has shut down. If this method is called with a non-zero timeout, a collection of notifications still in the push manager's internal retry queue will be returned. The returned collection will not contain notifications in the public queue (since callers can work with the public queue directly). When shutting down with a non-zero timeout, no guarantees are made that notifications that were sent (i.e. are in neither the public queue nor the retry queue) were actually received or processed by the APNs gateway.
If called with a timeout of 0
, the returned collection of unsent notifications will be empty. By the
time this method exits, all notifications taken from the public queue are guaranteed to have been delivered to
the APNs gateway and either accepted or rejected (i.e. the state of all sent notifications is known).
timeout
- the timeout, in milliseconds, after which client threads should be shut down as quickly as
possible; if 0
, this method will wait indefinitely for the retry queue to empty and connections to closePushManager
shut downInterruptedException
- if interrupted while waiting for connections to close cleanlyIllegalStateException
- if this method is called before the push manager has been startedpublic void registerRejectedNotificationListener(RejectedNotificationListener<? super T> listener)
Registers a listener for notifications rejected by APNs for specific reasons.
listener
- the listener to registerIllegalStateException
- if this push manager has already been shut downunregisterRejectedNotificationListener(RejectedNotificationListener)
public boolean unregisterRejectedNotificationListener(RejectedNotificationListener<? super T> listener)
Un-registers a rejected notification listener.
listener
- the listener to un-registertrue
if the given listener was registered with this push manager and removed or false
if
the listener was not already registered with this push managerpublic void registerFailedConnectionListener(FailedConnectionListener<? super T> listener)
Registers a listener for failed attempts to connect to the APNs gateway.
listener
- the listener to registerIllegalStateException
- if this push manager has already been shut downunregisterFailedConnectionListener(FailedConnectionListener)
public boolean unregisterFailedConnectionListener(FailedConnectionListener<? super T> listener)
Un-registers a connection failure listener.
listener
- the listener to un-registertrue
if the given listener was registered with this push manager and removed or false
if
the listener was not already registered with this push managerpublic String getName()
public BlockingQueue<T> getQueue()
Returns the queue of messages to be sent to the APNs gateway. Callers should add notifications to this queue
directly to send notifications. Notifications will be removed from this queue by Pushy when a send attempt is
started, but are not guaranteed to have reached the APNs gateway until the push manager has been shut down
without a timeout (see shutdown(long)
). Successful delivery is not acknowledged by the APNs
gateway. Notifications rejected by APNs for specific reasons will be passed to registered
RejectedNotificationListener
s, and notifications that could not be sent due to temporary I/O problems
will be scheduled for re-transmission in a separate, internal queue.
Notifications in this queue will only be consumed when the PushManager
is running, has active
connections, and the internal "retry queue" is empty.
registerRejectedNotificationListener(RejectedNotificationListener)
public void registerExpiredTokenListener(ExpiredTokenListener<? super T> listener)
requestExpiredTokens()
.listener
- the listener to registerIllegalStateException
- if this push manager has already been shut downunregisterExpiredTokenListener(ExpiredTokenListener)
,
requestExpiredTokens()
public boolean unregisterExpiredTokenListener(ExpiredTokenListener<? super T> listener)
Un-registers an expired token listener.
listener
- the listener to un-registertrue
if the given listener was registered with this push manager and removed or false
if
the listener was not already registered with this push managerpublic void requestExpiredTokens()
Begins an asynchronous attempt to get a list of expired tokens from the feedback service. Be warned that this is a destructive operation. According to Apple's documentation:
The feedback service’s list is cleared after you read it. Each time you connect to the feedback service, the information it returns lists only the failures that have happened since you last connected.
When a list of expired tokens has been gathered, registered expired token listeners will be notified
(see registerExpiredTokenListener(ExpiredTokenListener)
). If a feedback polling attempt
fails, registered failed connection listeners will be notified.
public void handleConnectionSuccess(FeedbackServiceConnection connection)
connection
- the connection that completed its connection attemptpublic void handleConnectionFailure(FeedbackServiceConnection connection, Throwable cause)
connection
- the connection that failed to connect to the APNs feedback servicecause
- the cause of the failurepublic void handleExpiredToken(FeedbackServiceConnection connection, ExpiredToken token)
connection
- the connection that received the expired tokentoken
- the expired tokenpublic void handleConnectionClosure(FeedbackServiceConnection connection)
connection
- the connection that has been disconnected and is no longer activepublic void handleConnectionSuccess(ApnsConnection<T> connection)
ApnsConnectionListener
handleConnectionSuccess
in interface ApnsConnectionListener<T extends ApnsPushNotification>
connection
- the connection that completed its connection attemptpublic void handleConnectionFailure(ApnsConnection<T> connection, Throwable cause)
ApnsConnectionListener
handleConnectionFailure
in interface ApnsConnectionListener<T extends ApnsPushNotification>
connection
- the connection that failed to connect to an APNs gatewaycause
- the cause of the failurepublic void handleConnectionWritabilityChange(ApnsConnection<T> connection, boolean writable)
ApnsConnectionListener
handleConnectionWritabilityChange
in interface ApnsConnectionListener<T extends ApnsPushNotification>
connection
- the connection whose writability has changedwritable
- true
if the connection has become writable or false
if it has become unwritablepublic void handleConnectionClosure(ApnsConnection<T> connection)
ApnsConnectionListener
handleConnectionClosure
in interface ApnsConnectionListener<T extends ApnsPushNotification>
connection
- the connection that has been disconnected and is no longer activepublic void handleWriteFailure(ApnsConnection<T> connection, T notification, Throwable cause)
ApnsConnectionListener
handleWriteFailure
in interface ApnsConnectionListener<T extends ApnsPushNotification>
connection
- the connection that attempted to deliver the notificationnotification
- the notification that could not be writtencause
- the cause of the write failurepublic void handleRejectedNotification(ApnsConnection<T> connection, T rejectedNotification, RejectedNotificationReason reason)
ApnsConnectionListener
handleRejectedNotification
in interface ApnsConnectionListener<T extends ApnsPushNotification>
connection
- the connection that sent the notification that was rejectedrejectedNotification
- the notification that was rejectedreason
- the reason for the rejectionApnsConnectionListener.handleConnectionClosure(ApnsConnection)
,
ApnsConnectionListener.handleUnprocessedNotifications(ApnsConnection, Collection)
public void handleUnprocessedNotifications(ApnsConnection<T> connection, Collection<T> unprocessedNotifications)
ApnsConnectionListener
handleUnprocessedNotifications
in interface ApnsConnectionListener<T extends ApnsPushNotification>
connection
- the connection that sent the notifications that were not processedunprocessedNotifications
- the notifications known to have not been processed by the APNs gatewayCopyright © 2013–2015 RelayRides. All rights reserved.