package com.dianping.pigeon.remoting.http.provider; import java.util.concurrent.TimeUnit; 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.common.util.InvocationUtils; import com.dianping.pigeon.remoting.invoker.Client; import com.dianping.pigeon.remoting.invoker.concurrent.CallFuture; import com.dianping.pigeon.remoting.invoker.concurrent.Callback; import com.dianping.pigeon.remoting.invoker.exception.RequestTimeoutException; import com.dianping.pigeon.remoting.provider.domain.ProviderContext; import com.dianping.pigeon.remoting.provider.util.ProviderUtils; /** * Created by chenchongze on 16/1/13. */ public class HttpCallbackFuture implements Callback, CallFuture { protected final Logger logger = LoggerLoader.getLogger(this.getClass()); protected InvocationRequest request; protected ProviderContext invocationContext; protected InvocationResponse response; private boolean done = false; public HttpCallbackFuture(InvocationRequest request, ProviderContext invocationContext) { this.request = request; this.invocationContext = invocationContext; } @Override public void run() { synchronized (this) { this.done = true; this.notifyAll(); } } @Override public InvocationResponse getResponse(long timeoutMillis) throws InterruptedException { synchronized (this) { long start = request.getCreateMillisTime(); while (!this.done) { long timeoutMillis_ = timeoutMillis - (System.currentTimeMillis() - start); if (timeoutMillis_ <= 0) { StringBuilder sb = new StringBuilder(); sb.append("request timeout, current time:").append(System.currentTimeMillis()) .append("\r\nrequest:").append(request); RequestTimeoutException e = InvocationUtils.newTimeoutException("invoke timeout"); invocationContext.getChannel().write(invocationContext, ProviderUtils.createFailResponse(request, e)); logger.error(sb.toString(), e); } else { this.wait(timeoutMillis_); } } } return null; } @Override public InvocationResponse getResponse() throws InterruptedException { return getResponse(Long.MAX_VALUE); } @Override public InvocationResponse getResponse(long timeout, TimeUnit unit) throws InterruptedException { return getResponse(unit.toMillis(timeout)); } @Override public void callback(InvocationResponse response) { this.response = response; } @Override public void setRequest(InvocationRequest request) { this.request = request; } @Override public boolean isDone() { return done; } @Override public boolean cancel() { return false; } @Override public boolean isCancelled() { return false; } @Override public void dispose() { } @Override public void setClient(Client client) { } @Override public Client getClient() { return null; } }