Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

When QUEUE Mode change thread sleep to wait. #12

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import javapns.devices.*;
import javapns.devices.exceptions.*;
import javapns.notification.*;
import org.apache.log4j.Logger;

/**
* <h1>Pushes payloads asynchroneously using a dedicated thread.</h1>
Expand All @@ -28,21 +29,22 @@
* @author Sylvain Pedneault
*/
public class NotificationThread implements Runnable, PushQueue {
static final Logger logger = Logger.getLogger(NotificationThread.class);

/**
* Working modes supported by Notification Threads.
*/
public static enum MODE {
/**
* In LIST mode, the thread is given a predefined list of devices and pushes all notifications as soon as it is started.
* In LIST mode, the thread is given a predefined list of devices and pushes all notifications as soon as it is started.
* Its work is complete, the connection is closed and the thread ends as soon as all notifications have been sent.
* This mode is appropriate when you have a large amount of notifications to send in one batch.
*/
LIST,

/**
* In QUEUE mode, the thread is started with an open connection and no notification to send, and waits for notifications to be queued.
* It opens a connection and waits for messages to be added to its queue using a queue(..) method.
* In QUEUE mode, the thread is started with an open connection and no notification to send, and waits for notifications to be queued.
* It opens a connection and waits for messages to be added to its queue using a queue(..) method.
* This mode is appropriate when you need to periodically send random individual notifications and you do not wish to open and close connections to Apple all the time (which is something Apple warns against in their documentation).
* Unless your software is constantly generating large amounts of random notifications and that you absolutely need to stream them over multiple threaded connections, you should not need to create more than one NotificationThread in QUEUE mode.
*/
Expand Down Expand Up @@ -72,12 +74,13 @@ public static enum MODE {
private List<PayloadPerDevice> messages = new Vector<PayloadPerDevice>();

private Exception exception;
private final Object queueModeWaitPoint = new Object();


/**
* Create a grouped thread in LIST mode for pushing a single payload to a list of devices
* and coordinating with a parent NotificationThreads object.
*
*
* @param threads the parent NotificationThreads object that is coordinating multiple threads
* @param notificationManager the notification manager to use
* @param server the server to communicate with
Expand All @@ -97,7 +100,7 @@ public NotificationThread(NotificationThreads threads, PushNotificationManager n
/**
* Create a grouped thread in LIST mode for pushing individual payloads to a list of devices
* and coordinating with a parent NotificationThreads object.
*
*
* @param threads the parent NotificationThreads object that is coordinating multiple threads
* @param notificationManager the notification manager to use
* @param server the server to communicate with
Expand All @@ -114,7 +117,7 @@ public NotificationThread(NotificationThreads threads, PushNotificationManager n

/**
* Create a standalone thread in LIST mode for pushing a single payload to a list of devices.
*
*
* @param notificationManager the notification manager to use
* @param server the server to communicate with
* @param payload a payload to push
Expand All @@ -127,7 +130,7 @@ public NotificationThread(PushNotificationManager notificationManager, AppleNoti

/**
* Create a standalone thread in LIST mode for pushing individual payloads to a list of devices.
*
*
* @param notificationManager the notification manager to use
* @param server the server to communicate with
* @param messages a list or an array of PayloadPerDevice: {@link java.util.List}<{@link javapns.notification.PayloadPerDevice}>, {@link javapns.notification.PayloadPerDevice PayloadPerDevice[]} or {@link javapns.notification.PayloadPerDevice}
Expand All @@ -139,7 +142,7 @@ public NotificationThread(PushNotificationManager notificationManager, AppleNoti

/**
* Create a grouped thread in QUEUE mode, awaiting messages to push.
*
*
* @param threads the parent NotificationThreads object that is coordinating multiple threads
* @param notificationManager the notification manager to use
* @param server the server to communicate with
Expand All @@ -155,7 +158,7 @@ public NotificationThread(NotificationThreads threads, PushNotificationManager n

/**
* Create a standalone thread in QUEUE mode, awaiting messages to push.
*
*
* @param notificationManager the notification manager to use
* @param server the server to communicate with
*/
Expand All @@ -166,7 +169,7 @@ public NotificationThread(PushNotificationManager notificationManager, AppleNoti

/**
* Create a standalone thread in QUEUE mode, awaiting messages to push.
*
*
* @param server the server to communicate with
*/
public NotificationThread(AppleNotificationServer server) {
Expand All @@ -176,7 +179,7 @@ public NotificationThread(AppleNotificationServer server) {

/**
* Start the transmission thread.
*
*
* This method returns immediately, as the thread starts working on its own.
*/
public synchronized NotificationThread start() {
Expand Down Expand Up @@ -276,8 +279,17 @@ private void runQueue() {
busy = false;
}
try {
Thread.sleep(10 * 1000);
} catch (Exception e) {
synchronized (queueModeWaitPoint) {
if (logger.isDebugEnabled()) {
logger.debug("thread #" + this.threadNumber + " wait message");
}
queueModeWaitPoint.wait(10 * 1000);
}
} catch (InterruptedException e) {
if (logger.isDebugEnabled()) {
logger.debug("thread #" + this.threadNumber + " interrupted.");
}
break;
}
}
notificationManager.stopConnection();
Expand Down Expand Up @@ -308,7 +320,9 @@ public PushQueue add(PayloadPerDevice message) {
if (mode != MODE.QUEUE) return this;
try {
messages.add(message);
this.thread.interrupt();
synchronized (queueModeWaitPoint) {
queueModeWaitPoint.notifyAll();
}
} catch (Exception e) {
}
return this;
Expand All @@ -319,9 +333,9 @@ public PushQueue add(PayloadPerDevice message) {
* Set a maximum number of notifications that should be streamed over a continuous connection
* to an Apple server. When that maximum is reached, the thread automatically closes and
* reopens a fresh new connection to the server and continues streaming notifications.
*
*
* Default is 200 (recommended).
*
*
* @param maxNotificationsPerConnection
*/
public void setMaxNotificationsPerConnection(int maxNotificationsPerConnection) {
Expand All @@ -338,9 +352,9 @@ public int getMaxNotificationsPerConnection() {
* Set a delay the thread should sleep between each notification.
* This is sometimes useful when communication with Apple servers is
* unreliable and notifications are streaming too fast.
*
*
* Default is 0.
*
*
* @param milliseconds
*/
public void setSleepBetweenNotifications(long milliseconds) {
Expand All @@ -360,7 +374,7 @@ void setDevices(List<Device> devices) {

/**
* Get the list of devices associated with this thread.
*
*
* @return a list of devices
*/
public List<Device> getDevices() {
Expand All @@ -370,7 +384,7 @@ public List<Device> getDevices() {

/**
* Get the number of devices that this thread pushes to.
*
*
* @return the number of devices registered with this thread
*/
public int size() {
Expand All @@ -380,7 +394,7 @@ public int size() {

/**
* Provide an event listener which will be notified of this thread's progress.
*
*
* @param listener any object implementing the NotificationProgressListener interface
*/
public void setListener(NotificationProgressListener listener) {
Expand All @@ -394,9 +408,9 @@ public NotificationProgressListener getListener() {


/**
* Set the thread number so that generated message identifiers can be made
* Set the thread number so that generated message identifiers can be made
* unique across all threads.
*
*
* @param threadNumber
*/
protected void setThreadNumber(int threadNumber) {
Expand All @@ -406,7 +420,7 @@ protected void setThreadNumber(int threadNumber) {

/**
* Return the thread number assigned by the parent NotificationThreads object, if any.
*
*
* @return the unique number assigned to this thread by the parent group
*/
public int getThreadNumber() {
Expand All @@ -416,7 +430,7 @@ public int getThreadNumber() {

/**
* Return a new sequential message identifier.
*
*
* @return a message identifier unique to all NotificationThread objects
*/
public int newMessageIdentifier() {
Expand All @@ -426,7 +440,7 @@ public int newMessageIdentifier() {

/**
* Returns the first message identifier generated by this thread.
*
*
* @return a message identifier unique to all NotificationThread objects
*/
public int getFirstMessageIdentifier() {
Expand All @@ -436,7 +450,7 @@ public int getFirstMessageIdentifier() {

/**
* Returns the last message identifier generated by this thread.
*
*
* @return a message identifier unique to all NotificationThread objects
*/
public int getLastMessageIdentifier() {
Expand All @@ -446,7 +460,7 @@ public int getLastMessageIdentifier() {

/**
* Returns list of all notifications pushed by this thread (successful or not).
*
*
* @return a list of pushed notifications
*/
public PushedNotifications getPushedNotifications() {
Expand All @@ -465,7 +479,7 @@ public void clearPushedNotifications() {

/**
* Returns list of all notifications that this thread attempted to push but that failed.
*
*
* @return a list of failed notifications
*/
public PushedNotifications getFailedNotifications() {
Expand All @@ -475,7 +489,7 @@ public PushedNotifications getFailedNotifications() {

/**
* Returns list of all notifications that this thread attempted to push and succeeded.
*
*
* @return a list of failed notifications
*/
public PushedNotifications getSuccessfulNotifications() {
Expand All @@ -494,7 +508,7 @@ void setMessages(List<PayloadPerDevice> messages) {

/**
* Get the messages associated with this thread, if any.
*
*
* @return messages
*/
public List<PayloadPerDevice> getMessages() {
Expand Down Expand Up @@ -522,7 +536,7 @@ public Exception getCriticalException() {

/**
* Wrap a critical exception (if any occurred) into a List to satisfy the NotificationQueue interface contract.
*
*
* @return a list containing a critical exception, if any occurred
*/
public List<Exception> getCriticalExceptions() {
Expand Down