Repository: apache/dubbo
File: dubbo-rpc/dubbo-rpc-dubbo/src/main/java/org/apache/dubbo/rpc/protocol/dubbo/DubboInvoker.java (Java)

Code before:

            invocation.setAttachment(TIMEOUT_KEY, String.valueOf(timeout));

            RpcContext.getServiceContext().setRemoteAddress(currentClient.getRemoteAddress());

            Integer payload = getUrl().getParameter(PAYLOAD, Integer.class);

            Request request = new Request();
            if (payload != null) {
                request.setPayload(payload);
            }
            request.setData(inv);
            request.setVersion(Version.getProtocolVersion());

            if (isOneway) {
                boolean isSent = getUrl().getMethodParameter(methodName, Constants.SENT_KEY, false);
                request.setTwoWay(false);
                currentClient.send(request, isSent);
                return AsyncRpcResult.newDefaultAsyncResult(invocation);
            } else {
                request.setTwoWay(true);
                ExecutorService executor = getCallbackExecutor(getUrl(), inv);
                CompletableFuture<AppResponse> appResponseFuture =
                    currentClient.request(request, timeout, executor).thenApply(AppResponse.class::cast);
                // save for 2.6.x compatibility, for example, TraceFilter in Zipkin uses com.alibaba.xxx.FutureAdapter
                if (((RpcInvocation) invocation).getInvokeMode() != InvokeMode.SYNC) {
                    FutureContext.getContext().setCompatibleFuture(appResponseFuture);
                }
                AsyncRpcResult result = new AsyncRpcResult(appResponseFuture, inv);
                result.setExecutor(executor);
                return result;
            }
        } catch (TimeoutException e) {
            throw new RpcException(RpcException.TIMEOUT_EXCEPTION, "Invoke remote method timeout. method: " + RpcUtils.getMethodName(invocation) + ", provider: " + getUrl() + ", cause: " + e.getMessage(), e);
        } catch (RemotingException e) {
            String remoteExpMsg = "Failed to invoke remote method: " + RpcUtils.getMethodName(invocation) + ", provider: " + getUrl() + ", cause: " + e.getMessage();
            if (e.getCause() instanceof IOException && e.getCause().getCause() instanceof SerializationException) {
                throw new RpcException(RpcException.SERIALIZATION_EXCEPTION, remoteExpMsg, e);
            } else {
                throw new RpcException(RpcException.NETWORK_EXCEPTION, remoteExpMsg, e);
            }
        }
    }

    @Override
    public boolean isAvailable() {
        if (!super.isAvailable()) {
            return false;
        }
        for (ExchangeClient client : clientsProvider.getClients()) {
            if (client.isConnected() && !client.hasAttribute(Constants.CHANNEL_ATTRIBUTE_READONLY_KEY)) {

Review comment (suggestion):
Check `private static final boolean setFutureWhenSync = Boolean.parseBoolean(System.getProperty(CommonConstants.SET_FUTURE_IN_SYNC_MODE, "true"));`

Code after:
                    "No time left for making the following call: " + invocation.getServiceName() + "."
                        + RpcUtils.getMethodName(invocation) + ", terminate directly."), invocation);
            }

            invocation.setAttachment(TIMEOUT_KEY, String.valueOf(timeout));

            RpcContext.getServiceContext().setRemoteAddress(currentClient.getRemoteAddress());

            Integer payload = getUrl().getParameter(PAYLOAD, Integer.class);

            Request request = new Request();
            if (payload != null) {
                request.setPayload(payload);
            }
            request.setData(inv);
            request.setVersion(Version.getProtocolVersion());

            if (isOneway) {
                boolean isSent = getUrl().getMethodParameter(methodName, Constants.SENT_KEY, false);
                request.setTwoWay(false);
                currentClient.send(request, isSent);
                return AsyncRpcResult.newDefaultAsyncResult(invocation);
            } else {
                request.setTwoWay(true);
                ExecutorService executor = getCallbackExecutor(getUrl(), inv);
                CompletableFuture<AppResponse> appResponseFuture =
                    currentClient.request(request, timeout, executor).thenApply(AppResponse.class::cast);
                // save for 2.6.x compatibility, for example, TraceFilter in Zipkin uses com.alibaba.xxx.FutureAdapter
                if (setFutureWhenSync || ((RpcInvocation) invocation).getInvokeMode() != InvokeMode.SYNC) {
                    FutureContext.getContext().setCompatibleFuture(appResponseFuture);
                }
                AsyncRpcResult result = new AsyncRpcResult(appResponseFuture, inv);
                result.setExecutor(executor);
                return result;
            }
        } catch (TimeoutException e) {
            throw new RpcException(RpcException.TIMEOUT_EXCEPTION, "Invoke remote method timeout. method: " + RpcUtils.getMethodName(invocation) + ", provider: " + getUrl() + ", cause: " + e.getMessage(), e);
        } catch (RemotingException e) {
            String remoteExpMsg = "Failed to invoke remote method: " + RpcUtils.getMethodName(invocation) + ", provider: " + getUrl() + ", cause: " + e.getMessage();
            if (e.getCause() instanceof IOException && e.getCause().getCause() instanceof SerializationException) {
                throw new RpcException(RpcException.SERIALIZATION_EXCEPTION, remoteExpMsg, e);
            } else {
                throw new RpcException(RpcException.NETWORK_EXCEPTION, remoteExpMsg, e);
            }
        }
    }

    @Override
    public boolean isAvailable() {
        if (!super.isAvailable()) {
            return false;