package net.contextfw.web.commons.cloud.internal.mongo; import java.util.Random; import java.util.concurrent.RejectedExecutionHandler; import java.util.concurrent.ScheduledThreadPoolExecutor; import java.util.concurrent.ThreadPoolExecutor; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.mongodb.BasicDBObject; import com.mongodb.BasicDBObjectBuilder; import com.mongodb.DB; import com.mongodb.DBCollection; import com.mongodb.DBObject; /** * For internal use only */ public abstract class MongoBase { private static final Logger LOG = LoggerFactory.getLogger(MongoBase.class); private final ThreadPoolExecutor executor; private final DB db; protected static final String KEY_HANDLE = "handle"; protected static final String KEY_VALID_THROUGH = "validThrough"; protected static final String KEY_LOCKED = "locked"; protected static final String KEY_REMOTE_ADDR = "remoteAddr"; private long nextCleanup = 0; private final long removalSchedulePeriod; protected MongoBase(DB db, long removalSchedulePeriod) { this.db = db; this.removalSchedulePeriod = removalSchedulePeriod; RejectedExecutionHandler handler = new RejectedExecutionHandler() { public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) { r.run(); } }; executor = new ScheduledThreadPoolExecutor(10, handler); } protected void setIndexes(DBCollection collection) { collection.ensureIndex(KEY_HANDLE); collection.ensureIndex(KEY_REMOTE_ADDR); } protected static DBObject o(String key, Object value) { return new BasicDBObject(key, value); } protected BasicDBObjectBuilder b() { return BasicDBObjectBuilder.start(); } protected DB getDb() { return db; } protected void removeExpiredObjects() { final long now = System.currentTimeMillis(); if (now > nextCleanup) { nextCleanup = now + new Random().nextInt((int) removalSchedulePeriod*2); executeAsync(new ExceptionSafeExecution() { public void execute() throws Exception { DBCollection collection = getCollection(); DBObject query = o(KEY_VALID_THROUGH, o("$lt", now)); if (LOG.isDebugEnabled()) { LOG.debug("Cleaning {} objects from {}", collection.count(query), collection.getName()); } collection.remove(query); } }); } } protected void executeAsync(ExceptionSafeExecution execution) { executor.execute(execution); } protected abstract DBCollection getCollection(); }