package com.pingan.emall.biz.util;
import java.util.Map;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import org.apache.log4j.Logger;
public class SystemEmailBlockingQueue {
private static final Logger LOG = Logger.getLogger(SystemEmailBlockingQueue.class);
private BlockingQueue<MailBean> queue;
private Map<MailBean, AtomicInteger> retryMap;
private static final int MAX_RETRY_COUNT = 3;
public SystemEmailBlockingQueue(int maxQueueSize) {
queue = new ArrayBlockingQueue<MailBean>(maxQueueSize);
retryMap = new ConcurrentHashMap<MailBean, AtomicInteger>();
}
/**
* Add mail request to queue
* Here we don't want the business thread blocked all the time,
* so here we use offer with 2 seconds timeout instead of put
* @param mail
* @return
*/
public boolean push(MailBean mail) {
try {
return queue.offer(mail, 2, TimeUnit.SECONDS);
} catch (InterruptedException e) {
LOG.error("Offer action of system email blocking queue interrupted", e);
return false;
}
}
/**
* Take one mail request from queue, if no mail bean in queue, thread blocked
* @return Mail bean
*/
public MailBean poll() {
MailBean mail = null;
try {
mail = queue.take();
} catch (InterruptedException e) {
LOG.error("Take action of System mail blocking queue interrupted", e);
}
return mail;
}
/**
* Resend if mail send failed and retry times less than max retry time
* @param mail detail mail bean
* @param succeed mail send result
*/
public void retry(MailBean mail, boolean sendSucceed) {
if (sendSucceed) {
// Mail send succeed, remove it from retry map if exists.
if (retryMap.containsKey(mail)) {
retryMap.remove(mail);
}
return;
}
AtomicInteger retryCount = retryMap.get(mail);
if (retryCount == null) {
// Mail send failed for the first time, append it into the end of queue,
// and add one signal retry count in send failed map
if (push(mail)) {
retryMap.put(mail, new AtomicInteger(1));
}
} else {
// retry count less than 3 times, re append into the end of queue
if (retryCount.incrementAndGet() <= MAX_RETRY_COUNT) {
if (!push(mail)) {
retryMap.remove(mail);
}
} else {
retryMap.remove(mail);
}
}
}
public int size() {
return queue.size();
}
public void destroy() {
queue.clear();
retryMap.clear();
}
}
import java.util.Map;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import org.apache.log4j.Logger;
public class SystemEmailBlockingQueue {
private static final Logger LOG = Logger.getLogger(SystemEmailBlockingQueue.class);
private BlockingQueue<MailBean> queue;
private Map<MailBean, AtomicInteger> retryMap;
private static final int MAX_RETRY_COUNT = 3;
public SystemEmailBlockingQueue(int maxQueueSize) {
queue = new ArrayBlockingQueue<MailBean>(maxQueueSize);
retryMap = new ConcurrentHashMap<MailBean, AtomicInteger>();
}
/**
* Add mail request to queue
* Here we don't want the business thread blocked all the time,
* so here we use offer with 2 seconds timeout instead of put
* @param mail
* @return
*/
public boolean push(MailBean mail) {
try {
return queue.offer(mail, 2, TimeUnit.SECONDS);
} catch (InterruptedException e) {
LOG.error("Offer action of system email blocking queue interrupted", e);
return false;
}
}
/**
* Take one mail request from queue, if no mail bean in queue, thread blocked
* @return Mail bean
*/
public MailBean poll() {
MailBean mail = null;
try {
mail = queue.take();
} catch (InterruptedException e) {
LOG.error("Take action of System mail blocking queue interrupted", e);
}
return mail;
}
/**
* Resend if mail send failed and retry times less than max retry time
* @param mail detail mail bean
* @param succeed mail send result
*/
public void retry(MailBean mail, boolean sendSucceed) {
if (sendSucceed) {
// Mail send succeed, remove it from retry map if exists.
if (retryMap.containsKey(mail)) {
retryMap.remove(mail);
}
return;
}
AtomicInteger retryCount = retryMap.get(mail);
if (retryCount == null) {
// Mail send failed for the first time, append it into the end of queue,
// and add one signal retry count in send failed map
if (push(mail)) {
retryMap.put(mail, new AtomicInteger(1));
}
} else {
// retry count less than 3 times, re append into the end of queue
if (retryCount.incrementAndGet() <= MAX_RETRY_COUNT) {
if (!push(mail)) {
retryMap.remove(mail);
}
} else {
retryMap.remove(mail);
}
}
}
public int size() {
return queue.size();
}
public void destroy() {
queue.clear();
retryMap.clear();
}
}