public boolean engineLoopProcessOne() {
// 1. select next batch size (maybe just 1 for now) where next
// consideration date is older than now
Subscription mySubscription = mainDao.getNextSendableSubscription(SubscriptionStatus.ACTIVE);
// if no result, then bail out, nothing to do
if (mySubscription == null) {
logger().debug("No more results, exiting loop");
return false;
}
// the subscription we are now processing
logger().debug("Got subscription with id: {}", mySubscription.getId());
// look up the subscriber too
Subscriber mySubscriber = mySubscription.getSubscriber();
if (mySubscriber == null) {
throw new RuntimeException("Data error, subscription with id " + mySubscription.getId() + " has null subscriber, should not be possible");
}
// Make sure we don't send to people who are asked off
// if status is not okay...
if (mySubscriber.getSubscriberStatus() != SubscriberStatus.OK) {
// end this subscription
endSubscription(mySubscription);
// log for posterity
logger().info("Was going to send to subscriber (email={}) but status is not OK, it's '{}', not sending and ending subscription.", mySubscriber.getEmail(), mySubscriber.getSubscriberStatus());
// bail out
return true;
}
// 2. for this Subscription, find last message processed in
// the list for that group
// first make sure we have a corresponding message group
MessageGroup myMessageGroup = messageGroupSource.getMessageGroupByName(mySubscription.getMessageGroupName());
// if no such message group, then we just get rid of the
// subscription (lose the date so it doesn't get pulled back up);
// also catch the case where no subscriber record, should never
// happen, but adding scenario for robustness)
if (myMessageGroup == null || mySubscriber == null) {
logger().warn(
"Either message group or subscriber was null, " +
"bailing out (messageGroup: {}, subscriber: {})",
myMessageGroup, mySubscriber);
/* ====================================================== */
/* clear next send date of subscription */
/* ====================================================== */
endSubscription(mySubscription);
return true;
}
// get the name of the last message
String myLastMessageName = mySubscription.getLastMessageName();
logger().debug("myLastMessageName: {}", myLastMessageName);
// if last message exists
int mySendMessageRefIndex = myMessageGroup.indexOfName(myLastMessageName);
if (mySendMessageRefIndex >= 0) {
// increment to next one to get the message we should send
mySendMessageRefIndex++;
}
// if last message name was null, then start at zero
if (myLastMessageName == null) {
mySendMessageRefIndex = 0;
}
logger().debug("myLastMessageRefIndex: {}", mySendMessageRefIndex);
// 3. get the next message
List<MessageRef> myMessageRefList = myMessageGroup.getMessageRefList();
// the MessageRef that we are to send
MessageRef mySendMessageRef = null;
if (mySendMessageRefIndex >= 0) {
// make sure we haven't gone beyond the end of the messages
if (myMessageRefList.size() > mySendMessageRefIndex) {
mySendMessageRef = myMessageRefList.get(mySendMessageRefIndex);
}
}
logger().debug("about to send mySendMessageRef: {}", mySendMessageRef);
// no message to send (either couldn't find last message or
// there is no next message); also check for the case where
// the last send date is not set (should never happen, but just
// to keep it from breaking the system we treat it like end
// of list)
if (mySendMessageRef == null || mySubscription.getLastSendDate() == null) {
logger().debug("no more messages to send for this subscription");
/* ====================================================== */
/* clear next send date of subscription */
/* ====================================================== */
endSubscription(mySubscription);
return true;
}
if (mySubscription.getLastSendDate() == null) {
logger().warn("last_send_date was null on subscription, should never happen");
}
// 3a.read the time on it and recalculate, confirm that
// time is now past
Long myWait = mySendMessageRef.getWaitAfterLastMessage();
if (myWait == null) {
/* ====================================================== */
/* clear next send date of subscription */
/* ====================================================== */
logger().warn("'wait after last message' value was not set for this message, ending the subscription");
endSubscription(mySubscription);
return true;
}
// 3b.if not past then set next consideration date to recalced date
// and kick back
// see if it's time to send yet
long myLastSendDate = mySubscription.getLastSendDate().getTime();
if (myLastSendDate + myWait > new Date().getTime()) {
logger().debug("it is not yet time to send this message, putting it back for later");
// not time to send (possibly message changed since
// this subscription record was last edited - also first
// subscription looks like this);
// reset the nextSendDate and move on
mySubscription.setNextSendDate(new Date(myLastSendDate + myWait));
mainDao.persist(mySubscription);
return true;
}
// 4. render and send message
boolean mySendWorked = sendMessage(
mySendMessageRef,
myMessageGroup,
mySubscriber,
mySubscription,
LogEntryType.MESSAGE_SENT
);
// if the sending was skipped...
if (!mySendWorked) {
// write a log entry for the skipping
mainDao.logEntry
(
LogEntryType.MESSAGE_SKIPPED,
mySubscriber,
myMessageGroup.getName(),
propUtil.mkprops(
"message_name", mySendMessageRef.getName()
)
);
}
// 5. get next message in the list and recalculate date based on that,
// update last message name and save
// update the last sent info
mySubscription.setLastMessageName(mySendMessageRef.getName());
mySubscription.setLastSendDate(new Date());
// index of next message
int myNextMessageRefIndex = mySendMessageRefIndex + 1;
// 5a.if no more messages, then next consideration date is set to null
if (myNextMessageRefIndex >= myMessageRefList.size()) {
mySubscription.setNextSendDate(null);
}
// if we have a next message, then calc when it fires
else {
MessageRef myNextMessageRef = myMessageRefList.get(myNextMessageRefIndex);
Long myNextWait = myNextMessageRef.getWaitAfterLastMessage();
mySubscription.setNextSendDate(
new Date(mySubscription.getLastSendDate().getTime() + myNextWait)
);
}
// save the changes to the subscription
mainDao.persist(mySubscription);
if (mySubscription.getNextSendDate() == null) {
// write a log entry for the completion of the subscription
mainDao.logEntry
(
LogEntryType.SUBSCRIPTION_DONE,