package com.rubiconproject.oss.kv.distributed.impl;
import java.util.Map;
import java.util.concurrent.Callable;
import java.util.concurrent.Future;
import java.util.concurrent.RejectedExecutionException;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import com.rubiconproject.oss.kv.KeyValueStore;
import com.rubiconproject.oss.kv.backends.ConnectionFactory;
import com.rubiconproject.oss.kv.backends.UriConnectionFactory;
import com.rubiconproject.oss.kv.distributed.Node;
import com.rubiconproject.oss.kv.distributed.Operation;
import com.rubiconproject.oss.kv.distributed.OperationCallback;
import com.rubiconproject.oss.kv.distributed.OperationQueue;
import com.rubiconproject.oss.kv.distributed.OperationResult;
import com.rubiconproject.oss.kv.distributed.OperationStatus;
public class NonPersistentThreadPoolOperationQueue extends
AbstractThreadPoolOperationQueue implements OperationQueue {
protected Log operationLog = LogFactory.getLog("haymitch.backendlog");
public NonPersistentThreadPoolOperationQueue(Map defaultProperties) {
this(defaultProperties, new UriConnectionFactory());
}
public NonPersistentThreadPoolOperationQueue(Map defaultProperties,
ConnectionFactory connectionFactory) {
this(defaultProperties, connectionFactory, DEFAULT_THREAD_POOL_COUNT,
DEFAULT_MAX_QUEUE_DEPTH);
}
public NonPersistentThreadPoolOperationQueue(Map defaultProperties,
ConnectionFactory connectionFactory, int threadPoolCount,
int maxQueueDepth) {
super(defaultProperties, connectionFactory, threadPoolCount,
maxQueueDepth);
}
public <V> Future<OperationResult<V>> submit(Operation<V> operation)
throws RejectedExecutionException {
return super.execute(new CallbackCallable<V>(operation));
}
private class CallbackCallable<V> implements Callable<OperationResult<V>> {
private long enqueueTime;
private Operation<V> op;
public CallbackCallable(Operation<V> op) {
this.op = op;
this.enqueueTime = System.currentTimeMillis();
}
public OperationResult<V> call() throws Exception {
OperationResult<V> result = null;
Node node = null;
long start = System.currentTimeMillis();
try {
node = op.getNode();
KeyValueStore store = connectionFactory.getStore(
defaultProperties, node.getConnectionURI());
Callable<OperationResult<V>> delegate = op.getCallable(store);
result = delegate.call();
} catch (Exception e) {
log.error("Exception fetching node", e);
result = new DefaultOperationResult<V>(op, null,
OperationStatus.Error, System.currentTimeMillis()
- start, e);
} finally {
try {
operationLog.info(String.format(
"%1$s_%2$s_%3$d %4$dms queue_time=%5$dms", op
.getName(), result.getStatus().toString()
.toLowerCase(), node.getId(), result
.getDuration(), start - enqueueTime));
} catch (Exception e) {
log.error("Exception writing to operation log", e);
}
OperationCallback<V> callback = op.getCallback();
if (callback != null) {
callback.completed(result);
}
}
return result;
}
}
}