All Downloads are FREE. Search and download functionalities are using the official Maven repository.
Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
com.github.jingshouyan.jrpc.client.JrpcClient Maven / Gradle / Ivy
package com.github.jingshouyan.jrpc.client;
import com.github.jingshouyan.jrpc.base.action.ActionHandler;
import com.github.jingshouyan.jrpc.base.action.ActionInterceptor;
import com.github.jingshouyan.jrpc.base.action.ActionInterceptorHolder;
import com.github.jingshouyan.jrpc.base.bean.Req;
import com.github.jingshouyan.jrpc.base.bean.Rsp;
import com.github.jingshouyan.jrpc.base.bean.ServerInfo;
import com.github.jingshouyan.jrpc.base.bean.Token;
import com.github.jingshouyan.jrpc.base.code.Code;
import com.github.jingshouyan.jrpc.base.exception.JrpcException;
import com.github.jingshouyan.jrpc.base.thrift.Jrpc;
import com.github.jingshouyan.jrpc.base.thrift.ReqBean;
import com.github.jingshouyan.jrpc.base.thrift.RspBean;
import com.github.jingshouyan.jrpc.base.thrift.TokenBean;
import com.github.jingshouyan.jrpc.base.util.rsp.RspUtil;
import com.github.jingshouyan.jrpc.client.config.ClientConfig;
import com.github.jingshouyan.jrpc.client.discover.ZkDiscover;
import com.github.jingshouyan.jrpc.client.node.Node;
import com.github.jingshouyan.jrpc.client.pool.TransportPool;
import com.github.jingshouyan.jrpc.client.transport.Transport;
import com.google.common.util.concurrent.ThreadFactoryBuilder;
import lombok.extern.slf4j.Slf4j;
import org.apache.thrift.async.AsyncMethodCallback;
import reactor.core.publisher.Mono;
import reactor.core.publisher.MonoSink;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.*;
import java.util.function.BiConsumer;
import java.util.stream.Collectors;
/**
* @author jingshouyan
* #date 2018/10/26 9:42
*/
@Slf4j
public class JrpcClient implements ActionHandler {
private ClientConfig config;
private ZkDiscover zkDiscover;
private final ExecutorService callbackExec;
private final BiConsumer, Rsp> success;
private final BiConsumer, Exception> error;
public JrpcClient(ClientConfig config) {
this.config = config;
this.zkDiscover = new ZkDiscover(config);
//callback 执行线程池
callbackExec = new ThreadPoolExecutor(config.getCallbackThreadPoolSize(),
config.getCallbackThreadPoolSize(), 0, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<>(),
new ThreadFactoryBuilder().setNameFormat("callback-%d").build(),
new ThreadPoolExecutor.CallerRunsPolicy()
);
//success 执行方法
success = (monoSink, rsp) -> monoSink.success(rsp);
// callbackExec.execute(() -> emitter.onSuccess(rsp));
//error 执行方法
error = (monoSink, e) -> {
Rsp rsp;
if (e instanceof JrpcException) {
rsp = RspUtil.error((JrpcException) e);
} else if (e instanceof TimeoutException) {
rsp = RspUtil.error(Code.CONNECT_TIMEOUT);
log.warn("call rpc timeout.", e);
} else {
rsp = RspUtil.error(Code.CLIENT_ERROR);
log.error("call rpc error.", e);
}
success.accept(monoSink, rsp);
};
}
public Map> serverMap() {
Map> nodeMap = zkDiscover.nodeMap();
Map> map = new HashMap<>(nodeMap.size());
for (Map.Entry> entry : nodeMap.entrySet()) {
String key = entry.getKey();
List value = entry.getValue().stream()
.map(Node::getServerInfo).collect(Collectors.toList());
map.put(key, value);
}
return map;
}
@Override
public Mono handle(Token token, Req req) {
ActionHandler handler = this::call;
for (ActionInterceptor interceptor : ActionInterceptorHolder.getClientInterceptors()) {
final ActionHandler ah = handler;
handler = (t, r) -> interceptor.around(t, r, ah);
}
Mono mono = handler.handle(token, req);
return mono;
}
private Mono call(Token token, Req req) {
return Mono.create(monoSink -> {
TransportPool pool = null;
Transport transport = null;
Rsp rsp;
try {
Node node = zkDiscover.getNode(req.getRouter());
pool = node.pool();
transport = pool.get();
TransportPool poolTmp = pool;
Transport transportTmp = transport;
Jrpc.AsyncClient client = transport.getAsyncClient();
TokenBean tokenBean = token.tokenBean();
ReqBean reqBean = req.reqBean();
if (req.isOneway()) {
client.send(tokenBean, reqBean, new AsyncMethodCallback() {
@Override
public void onComplete(Void aVoid) {
restore(poolTmp, transportTmp);
success.accept(monoSink, RspUtil.success());
}
@Override
public void onError(Exception e) {
invalid(poolTmp, transportTmp);
error.accept(monoSink, e);
}
});
} else {
client.call(tokenBean, reqBean, new AsyncMethodCallback() {
@Override
public void onComplete(RspBean rspBean) {
restore(poolTmp, transportTmp);
success.accept(monoSink, new Rsp(rspBean));
}
@Override
public void onError(Exception e) {
invalid(poolTmp, transportTmp);
error.accept(monoSink, e);
}
});
}
return;
} catch (JrpcException e) {
restore(pool, transport);
rsp = RspUtil.error(e);
} catch (TimeoutException e) {
restore(pool, transport);
rsp = RspUtil.error(Code.CONNECT_TIMEOUT);
} catch (Throwable e) {
log.error("call rpc error.", e);
invalid(pool, transport);
rsp = RspUtil.error(Code.CLIENT_ERROR);
}
monoSink.success(rsp);
});
}
private static void restore(TransportPool pool, Transport transport) {
if (pool != null && transport != null) {
pool.restore(transport);
}
}
private static void invalid(TransportPool pool, Transport transport) {
if (pool != null && transport != null) {
pool.invalid(transport);
}
}
}