use of com.alipay.sofa.rpc.core.exception.SofaRpcException in project sofa-rpc by sofastack.
the class SofaResponseFuture method getResponse.
/**
* get response
* <p>
* If remoting get exception, framework will wrapped it to SofaRpcException
*
* @param timeout get timeout
* @param clear true: framework will clear the ThreadLocal when return
* @return The response
* @throws SofaRpcException When throw SofaRpcException
* @throws InterruptedException
* if any thread has interrupted the current thread. The
* <i>interrupted status</i> of the current thread is
* cleared when this exception is thrown.
*/
public static Object getResponse(long timeout, boolean clear) throws SofaRpcException, InterruptedException {
RpcInvokeContext context = RpcInvokeContext.getContext();
Future future = context.getFuture();
if (null == future) {
throw new SofaRpcException(RpcErrorType.CLIENT_UNDECLARED_ERROR, LogCodes.getLog(LogCodes.ERROR_RESPONSE_FUTURE_NULL, Thread.currentThread()));
}
try {
if (clear) {
context.setFuture(null);
}
return future.get(timeout, TimeUnit.MILLISECONDS);
} catch (TimeoutException ex) {
// Future设置为超时
if (!future.isDone()) {
throw new SofaTimeOutException("Future is not done when timeout.", ex);
} else {
throw new SofaTimeOutException(ex.getMessage(), ex);
}
} catch (ExecutionException ex) {
Throwable cause = ex.getCause();
if (cause instanceof SofaRpcException) {
throw (SofaRpcException) cause;
} else {
throw new SofaRpcException(RpcErrorType.SERVER_UNDECLARED_ERROR, cause.getMessage(), cause);
}
}
}
use of com.alipay.sofa.rpc.core.exception.SofaRpcException in project sofa-rpc by sofastack.
the class SofaResponseFuture method getFuture.
/**
* @param clear 是否清除线程上下文
* @return 原生 Java Future 对象
* @throws SofaRpcException 当前线程上下文没有值的时候
*/
public static Future getFuture(boolean clear) throws SofaRpcException {
RpcInvokeContext context = RpcInvokeContext.getContext();
Future future = context.getFuture();
if (future == null) {
throw new SofaRpcException(RpcErrorType.CLIENT_UNDECLARED_ERROR, LogCodes.getLog(LogCodes.ERROR_RESPONSE_FUTURE_NULL, Thread.currentThread()));
}
if (clear) {
context.setFuture(null);
}
return future;
}
use of com.alipay.sofa.rpc.core.exception.SofaRpcException in project sofa-rpc by sofastack.
the class CallbackClientMain method main.
public static void main(String[] args) throws InterruptedException {
ApplicationConfig applicationConfig = new ApplicationConfig().setAppName("future-server");
ConsumerConfig<HelloService> consumerConfig = new ConsumerConfig<HelloService>().setApplication(applicationConfig).setInterfaceId(HelloService.class.getName()).setInvokeType(RpcConstants.INVOKER_TYPE_CALLBACK).setTimeout(5000).setOnReturn(new SofaResponseCallback() {
@Override
public void onAppResponse(Object appResponse, String methodName, RequestBase request) {
LOGGER.info("Interface get result: {}", appResponse);
}
@Override
public void onAppException(Throwable throwable, String methodName, RequestBase request) {
LOGGER.info("Interface get app exception: {}", throwable);
}
@Override
public void onSofaException(SofaRpcException sofaException, String methodName, RequestBase request) {
LOGGER.info("Interface get sofa exception: {}", sofaException);
}
}).setDirectUrl("bolt://127.0.0.1:22222?appName=future-server");
HelloService helloService = consumerConfig.refer();
LOGGER.warn("started at pid {}", RpcRuntimeContext.PID);
try {
for (int i = 0; i < 100; i++) {
try {
String s = helloService.sayHello("xxx", 22);
LOGGER.warn("{}", s);
} catch (Exception e) {
LOGGER.error(e.getMessage(), e);
}
try {
Thread.sleep(2000);
} catch (Exception e) {
}
}
} catch (Exception e) {
LOGGER.error("", e);
}
synchronized (CallbackClientMain.class) {
while (true) {
CallbackClientMain.class.wait();
}
}
}
use of com.alipay.sofa.rpc.core.exception.SofaRpcException in project sofa-rpc by sofastack.
the class BoltServerProcessor method handleRequest.
@Override
public void handleRequest(BizContext bizCtx, AsyncContext asyncCtx, SofaRequest request) {
// RPC内置上下文
RpcInternalContext context = RpcInternalContext.getContext();
context.setProviderSide(true);
String appName = request.getTargetAppName();
if (appName == null) {
// 默认全局appName
appName = (String) RpcRuntimeContext.get(RpcRuntimeContext.KEY_APPNAME);
}
// 是否链路异步化中
boolean isAsyncChain = false;
try {
// 这个 try-finally 为了保证Context一定被清理
// 统计值加1
processingCount.incrementAndGet();
// 远程地址
context.setRemoteAddress(bizCtx.getRemoteHost(), bizCtx.getRemotePort());
// 远程返回的通道
context.setAttachment(RpcConstants.HIDDEN_KEY_ASYNC_CONTEXT, asyncCtx);
InvokeContext boltInvokeCtx = bizCtx.getInvokeContext();
if (RpcInternalContext.isAttachmentEnable()) {
if (boltInvokeCtx != null) {
// rpc线程池等待时间 Long
putToContextIfNotNull(boltInvokeCtx, InvokeContext.BOLT_PROCESS_WAIT_TIME, context, RpcConstants.INTERNAL_KEY_PROCESS_WAIT_TIME);
}
}
putToContext(boltInvokeCtx);
if (EventBus.isEnable(ServerReceiveEvent.class)) {
EventBus.post(new ServerReceiveEvent(request));
}
// 开始处理
// 响应,用于返回
SofaResponse response = null;
// 异常,用于记录
Throwable throwable = null;
ProviderConfig providerConfig = null;
String serviceName = request.getTargetServiceUniqueName();
try {
// 这个try-catch 保证一定有Response
invoke: {
if (!boltServer.isStarted()) {
// 服务端已关闭
throwable = new SofaRpcException(RpcErrorType.SERVER_CLOSED, LogCodes.getLog(LogCodes.WARN_PROVIDER_STOPPED, SystemInfo.getLocalHost() + ":" + boltServer.serverConfig.getPort()));
response = MessageBuilder.buildSofaErrorResponse(throwable.getMessage());
break invoke;
}
if (bizCtx.isRequestTimeout()) {
// 加上丢弃超时的请求的逻辑
throwable = clientTimeoutWhenReceiveRequest(appName, serviceName, bizCtx.getRemoteAddress());
break invoke;
}
// 查找服务
Invoker invoker = boltServer.findInvoker(serviceName);
if (invoker == null) {
throwable = cannotFoundService(appName, serviceName);
response = MessageBuilder.buildSofaErrorResponse(throwable.getMessage());
break invoke;
}
if (invoker instanceof ProviderProxyInvoker) {
providerConfig = ((ProviderProxyInvoker) invoker).getProviderConfig();
// 找到服务后,打印服务的appName
appName = providerConfig != null ? providerConfig.getAppName() : null;
}
// 查找方法
String methodName = request.getMethodName();
Method serviceMethod = ReflectCache.getOverloadMethodCache(serviceName, methodName, request.getMethodArgSigs());
if (serviceMethod == null) {
throwable = cannotFoundServiceMethod(appName, methodName, serviceName);
response = MessageBuilder.buildSofaErrorResponse(throwable.getMessage());
break invoke;
} else {
request.setMethod(serviceMethod);
}
// 真正调用
response = doInvoke(serviceName, invoker, request);
if (bizCtx.isRequestTimeout()) {
// 加上丢弃超时的响应的逻辑
throwable = clientTimeoutWhenSendResponse(appName, serviceName, bizCtx.getRemoteAddress());
break invoke;
}
}
} catch (Exception e) {
// 服务端异常,不管是啥异常
LOGGER.errorWithApp(appName, "Server Processor Error!", e);
throwable = e;
response = MessageBuilder.buildSofaErrorResponse(e.getMessage());
}
// Response不为空,代表需要返回给客户端
if (response != null) {
RpcInvokeContext invokeContext = RpcInvokeContext.peekContext();
isAsyncChain = CommonUtils.isTrue(invokeContext != null ? (Boolean) invokeContext.remove(RemotingConstants.INVOKE_CTX_IS_ASYNC_CHAIN) : null);
// 如果是服务端异步代理模式,特殊处理,因为该模式是在业务代码自主异步返回的
if (!isAsyncChain) {
// 其它正常请求
try {
// 这个try-catch 保证一定要记录tracer
asyncCtx.sendResponse(response);
} finally {
if (EventBus.isEnable(ServerSendEvent.class)) {
EventBus.post(new ServerSendEvent(request, response, throwable));
}
}
}
}
} catch (Throwable e) {
// 可能有返回时的异常
if (LOGGER.isErrorEnabled(appName)) {
LOGGER.errorWithApp(appName, e.getMessage(), e);
}
} finally {
processingCount.decrementAndGet();
if (!isAsyncChain) {
if (EventBus.isEnable(ServerEndHandleEvent.class)) {
EventBus.post(new ServerEndHandleEvent());
}
}
RpcInvokeContext.removeContext();
RpcInternalContext.removeAllContext();
}
}
use of com.alipay.sofa.rpc.core.exception.SofaRpcException in project sofa-rpc by sofastack.
the class BoltClientTransport method syncSend.
@Override
public SofaResponse syncSend(SofaRequest request, int timeout) throws SofaRpcException {
checkConnection();
RpcInternalContext context = RpcInternalContext.getContext();
InvokeContext boltInvokeContext = createInvokeContext(request);
SofaResponse response = null;
SofaRpcException throwable = null;
try {
beforeSend(context, request);
response = doInvokeSync(request, boltInvokeContext, timeout);
return response;
} catch (Exception e) {
// 其它异常
throwable = convertToRpcException(e);
throw throwable;
} finally {
afterSend(context, boltInvokeContext, request);
if (EventBus.isEnable(ClientSyncReceiveEvent.class)) {
EventBus.post(new ClientSyncReceiveEvent(transportConfig.getConsumerConfig(), transportConfig.getProviderInfo(), request, response, throwable));
}
}
}
Aggregations