package io.robe.mail; import io.robe.mail.queue.InMemoryMailQueue; import io.robe.mail.queue.MailQueue; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * A queue and consumer thread implementation. * Sender thread wakes up on every item insert and works until queue goes empty. * Every item in queue will be send only once. If any error occurs it is the developers responsibility to handle it. {@link io.robe.mail.MailEvent}. */ public class MailManager { private static final Logger LOGGER = LoggerFactory.getLogger(MailManager.class); private static final MailQueue<MailItem> queue = new InMemoryMailQueue(); private static MailSender sender; private static Thread consumerThread = new Thread(); private static Runnable consumer = new Runnable() { @Override public void run() { LOGGER.debug("Starting mail thread."); // Check queue and continue until it is empty. while (!queue.isEmpty()) { // Take first and remove from queue MailItem item = queue.poll(); LOGGER.info("Sending: " + item.getId() + " (" + queue.size() + ")"); // Decide to call events. boolean hasEvent = item.getEvent() != null; if (hasEvent) { item.getEvent().before(item); } try { // Send it! sender.sendMessage(item); LOGGER.info("Success: " + item.getId() + " (" + queue.size() + ")"); if (hasEvent) { item.getEvent().success(item); } } catch (Exception e) { LOGGER.info("Failed: " + item.getId() + " (" + queue.size() + ")"); LOGGER.debug(item.toString(), e); if (hasEvent) { item.getEvent().error(item, e); } } } LOGGER.debug("Stopping mail thread."); } }; static void setSender(MailSender sender) { MailManager.sender = sender; } public static boolean hasConfiguration() { try { return sender.getConfiguration() != null; } catch (Exception e) { return false; } } /** * Takes the mail item into the queue and manages the mail sender thread. * If thread is alive it will send the mail at the end of current thread queue. * Else a new thread will be created and started. * * @param item MailItem to send. * @return true if item added to the queue successfully. */ public static boolean sendMail(MailItem item) { LOGGER.debug("Mail : " + item.toString()); boolean result = queue.add(item); LOGGER.info("Adding mail to queue. Queue size: " + queue.size()); // If thread is alive leave the job to it // Else create new thread and start. if (!consumerThread.isAlive()) { consumerThread = new Thread(consumer); consumerThread.start(); } return result; } }