/**
* Dianping.com Inc.
* Copyright (c) 2003-2013 All Rights Reserved.
*/
package com.dianping.pigeon.remoting.invoker.service;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import com.dianping.pigeon.log.Logger;
import com.dianping.pigeon.log.LoggerLoader;
import com.dianping.pigeon.remoting.common.domain.InvocationRequest;
import com.dianping.pigeon.remoting.common.domain.InvocationResponse;
import com.dianping.pigeon.remoting.invoker.Client;
import com.dianping.pigeon.remoting.invoker.concurrent.Callback;
import com.dianping.pigeon.remoting.invoker.domain.RemoteInvocationBean;
import com.dianping.pigeon.remoting.invoker.listener.InvocationTimeoutListener;
import com.dianping.pigeon.remoting.invoker.route.statistics.ServiceStatisticsHolder;
import com.dianping.pigeon.threadpool.DefaultThreadPool;
import com.dianping.pigeon.threadpool.ThreadPool;
import com.dianping.pigeon.util.ThreadPoolUtils;
public class ServiceInvocationRepository {
private static final Logger logger = LoggerLoader.getLogger(ServiceInvocationRepository.class);
private static Map<Long, RemoteInvocationBean> invocations = new ConcurrentHashMap<Long, RemoteInvocationBean>();
private static ServiceInvocationRepository instance = new ServiceInvocationRepository();
private static ThreadPool invocatinTimeCheckThreadPool = new DefaultThreadPool(
"Pigeon-Client-Invoke-Timeout-Check-ThreadPool");
public static ServiceInvocationRepository getInstance() {
return instance;
}
public void put(long sequence, RemoteInvocationBean invocation) {
invocations.put(sequence, invocation);
}
public InvocationRequest get(long sequence) {
RemoteInvocationBean bean = invocations.get(sequence);
return bean == null ? null : bean.request;
}
public void remove(long sequence) {
invocations.remove(sequence);
}
public void receiveResponse(InvocationResponse response) {
RemoteInvocationBean invocationBean = invocations.get(response.getSequence());
if (invocationBean != null) {
if (logger.isDebugEnabled()) {
logger.debug("received response:" + response);
}
InvocationRequest request = invocationBean.request;
try {
Callback callback = invocationBean.callback;
if (callback != null) {
Client client = callback.getClient();
if (client != null) {
ServiceStatisticsHolder.flowOut(request, client.getAddress());
}
callback.callback(response);
callback.run();
}
} finally {
invocations.remove(response.getSequence());
}
}
}
public void init() {
Runnable invocationTimeoutCheck = new InvocationTimeoutListener(invocations);
invocatinTimeCheckThreadPool.execute(invocationTimeoutCheck);
}
public void destroy() throws Exception {
ThreadPoolUtils.shutdown(invocatinTimeCheckThreadPool.getExecutor());
}
}