use of info.xiancloud.core.message.UnitRequest in project xian by happyyangyuan.
the class RpcServerDefaultHandler method processMsg.
private void processMsg(final ChannelHandlerContext ctx, final JSONObject json) {
try {
IdManager.makeSureMsgId(json);
if (MessageType.isDefaultRequest(json)) {
UnitRequest request = json.toJavaObject(UnitRequest.class);
request.getContext().setFromRemote(true);
String group = request.getContext().getGroup(), unit = request.getContext().getUnit();
final Consumer<String> backPayloadConsumerOnFailure = payload -> {
LOG.info("rpc server --> client发送失败了,因此这里复用当前长连接响应消息");
ctx.writeAndFlush(payload + Constant.RPC_DELIMITER);
};
ISequencer.build(group, unit, json).sequence(// call this sender if sequencer is succeeded.
new DefaultLocalAsyncSender(request, new NotifyHandler() {
protected void handle(UnitResponse unitResponse) {
LocalNodeManager.sendBack(unitResponse, backPayloadConsumerOnFailure);
}
}), /*failed directly, call this handler*/
new NotifyHandler() {
protected void handle(UnitResponse failureOut) {
LocalNodeManager.sendBack(failureOut, backPayloadConsumerOnFailure);
}
});
} else if (MessageType.isDefaultResponse(json)) {
LOG.debug("这是非常重要的说明:" + "1、客户端发给外部节点的请求期待的响应内容,服务端节在准备好响应结果后立刻与请求端新建一个rpc长连接/复用已存在的长连接,将响应写回去;" + "2、停服务时本地server会先停止,server停止就会关闭socket和server的io线程池,由于server的io线程池和业务线程池是分离的," + "业务线程池会继续运行直到所有任务处理完毕为止。此时,本节点不再有能力接收外部请求了,但是:" + "a.在即将停止的节点内,业务线程池任然需要向外部发送请求以完成业务操作,以及得到响应结果,因此client必须保持打开的。" + "b.在即将停止的节点内,业务线程池需要将本地执行结果返回给远程,这时候server已停,无法复用原管道将结果写回去,因此必须使用依然存活的client" + "将结果写回。" + "因此,有如下逻辑:所有server优先复用当前管道将响应写回去,当SERVER关闭后,业务线程池中后续任务通过未停止的client回写响应结果。");
UnitResponse response = json.toJavaObject(UnitResponse.class);
String ssid = response.getContext().getSsid();
ThreadPoolManager.execute(() -> {
NotifyHandler callback = LocalNodeManager.handleMap.getIfPresent(ssid);
if (callback != null) {
LocalNodeManager.handleMap.invalidate(ssid);
callback.callback(UnitResponse.create(json));
} else {
LOG.error(String.format("ssid=%s的消息没有找到对应的notifyHandler!整个消息内容=%s,", ssid, json), new Throwable());
}
}, response.getContext().getMsgId());
} else
LOG.error("rpc server端只支持request和response两种消息类型,不支持:" + MessageType.getMessageType(json), new RuntimeException());
} catch (Throwable e) {
LOG.error(e);
} finally {
MsgIdHolder.clear();
}
}
use of info.xiancloud.core.message.UnitRequest in project xian by happyyangyuan.
the class CacheListLengthUnit method execute.
@Override
public UnitResponse execute(UnitRequest msg) {
String key = msg.getArgMap().get("key").toString();
CacheConfigBean cacheConfigBean = msg.get("cacheConfig", CacheConfigBean.class);
long length = 0L;
try {
length = Redis.call(cacheConfigBean, (jedis) -> jedis.llen(key));
} catch (Exception e) {
return UnitResponse.exception(e);
}
return UnitResponse.success(length);
}
use of info.xiancloud.core.message.UnitRequest in project xian by happyyangyuan.
the class CacheListGetByIndexUnit method execute.
@Override
public UnitResponse execute(UnitRequest msg) {
String key = msg.getArgMap().get("key").toString();
Long index = msg.getArgMap().get("index") != null ? Long.parseLong(msg.getArgMap().get("index").toString()) : 0;
CacheConfigBean cacheConfigBean = msg.get("cacheConfig", CacheConfigBean.class);
String element = null;
try {
element = Redis.call(cacheConfigBean, (jedis) -> jedis.lindex(key, index));
if (element != null && element.toString().equals("nil"))
element = null;
} catch (Exception e) {
return UnitResponse.exception(e);
}
return UnitResponse.success(element);
}
use of info.xiancloud.core.message.UnitRequest in project xian by happyyangyuan.
the class HttpUnit method execute.
@Override
public UnitResponse execute(UnitRequest msg) {
ObjectInputStream ois = null;
try {
String reqBase64 = msg.get("req", String.class);
ois = new ObjectInputStream(new ByteArrayInputStream(Base64.getDecoder().decode(reqBase64)));
Request request = (Request) ois.readObject();
Response response;
try {
response = request.executeLocal();
} catch (ConnectException e) {
return UnitResponse.error(ISocketGroup.CODE_CONNECT_TIMEOUT, null, "Connect timeout: " + request.getUrl());
} catch (SocketTimeoutException e) {
return UnitResponse.error(ISocketGroup.CODE_SOCKET_TIMEOUT, null, "Read timeout: " + request.getUrl());
} catch (Throwable e) {
return UnitResponse.exception(e);
}
JSONObject retJson = new JSONObject();
retJson.put("status", response.getStatus());
retJson.put("headers", response.getHeaders());
retJson.put("entity", response.string());
return UnitResponse.success(retJson);
} catch (Throwable e) {
return UnitResponse.exception(e);
} finally {
}
}
use of info.xiancloud.core.message.UnitRequest in project xian by happyyangyuan.
the class AbstractBodyRequiredAsyncForwarder method bodyParams.
@Override
protected UnitRequest bodyParams(String body, Map<String, String> headerIgnored) {
UnitRequest controllerRequest = UnitRequest.create();
controllerRequest.getContext().setBody(body);
return controllerRequest;
}
Aggregations