Search in sources :

Example 16 with UnitResponse

use of info.xiancloud.core.message.UnitResponse in project xian by happyyangyuan.

the class Recorder method handleRecordItem.

private void handleRecordItem(Unit unit, UnitRequest request, UnitResponse response, Object beforeReturn) {
    String msgId = MsgIdHolder.get();
    Map<String, Object> map = new HashMap<>();
    map.put("msgId", String.valueOf(msgId.hashCode()));
    map.put("group", unit.getGroup().getName());
    map.put("unit", unit.getName());
    map.put("requestMap", request.argJson().toJSONString());
    map.put("responseCode", response.getCode());
    map.put("responseData", response.getData() != null ? response.getData().toString() : "");
    map.put("requestTime", beforeReturn.toString());
    map.put("responseTime", String.valueOf(System.currentTimeMillis()));
    map.put("cost", String.valueOf(System.currentTimeMillis() - Long.parseLong(beforeReturn.toString())));
    Xian.call("recorder", "actionItemRecord", map, new NotifyHandler() {

        protected void handle(UnitResponse unitResponse) {
            LOG.info(unitResponse.toJSONString());
        }
    });
}
Also used : HashMap(java.util.HashMap) UnitResponse(info.xiancloud.core.message.UnitResponse) NotifyHandler(info.xiancloud.core.NotifyHandler)

Example 17 with UnitResponse

use of info.xiancloud.core.message.UnitResponse in project xian by happyyangyuan.

the class NonblockingMqttCallBack method messageArrived.

@Override
public void messageArrived(String topicIgnored, MqttMessage message) throws Exception {
    try {
        /*第一个参数如果包含"."会被eclipse paho转为"/",所以,不要依赖这个参数!*/
        String msgFullStr = message.toString();
        JSONObject json = JSONObject.parseObject(msgFullStr);
        IdManager.makeSureMsgId(json);
        MessageType messageType = MessageType.getMessageType(json);
        switch(messageType) {
            case offline:
                LOG.info(String.format("离线广播: %s", json));
                break;
            case request:
                UnitRequest request = Reflection.toType(json, UnitRequest.class);
                logMqttFly(request, msgFullStr);
                String group = request.getContext().getGroup(), unit = request.getContext().getUnit();
                request.getContext().setFromRemote(true);
                ISequencer.build(group, unit, json).sequence(// run this runnable if succeeded.
                () -> new DefaultLocalAsyncSender(request, new NotifyHandler() {

                    protected void handle(UnitResponse unitResponse) {
                        LocalNodeManager.sendBack(unitResponse);
                    }
                }).send(), /*failed directly, call this handler*/
                new NotifyHandler() {

                    protected void handle(UnitResponse unitResponse) {
                        LocalNodeManager.sendBack(unitResponse);
                    }
                });
                break;
            case response:
                LOG.debug("ssid只在远程请求和响应时才会有值");
                UnitResponse response = Reflection.toType(json, UnitResponse.class);
                logMqttFly(response, msgFullStr);
                String ssid = response.getContext().getSsid();
                NotifyHandler handler = LocalNodeManager.handleMap.getIfPresent(ssid);
                LocalNodeManager.handleMap.invalidate(ssid);
                UnitResponse responseUnitResponse = UnitResponse.create(json);
                if (handler == null) {
                    LOG.error(String.format("ssid=%s的消息没有找到对应的notifyHandler!整个消息内容=%s,", ssid, json), new Throwable());
                    break;
                }
                try {
                    ThreadPoolManager.execute(() -> {
                        handler.callback(responseUnitResponse);
                    });
                } catch (RejectedExecutionException threadPoolAlreadyShutdown) {
                    LOG.info("线程池已关闭,这里使用临时线程执行任务,针对停服务时线程池已关闭的情况。");
                    new Thread(() -> handler.callback(responseUnitResponse)).start();
                }
                break;
            default:
                LOG.error("未知的mqtt消息类型:" + messageType, new RuntimeException());
        }
    } catch (Throwable e) {
        LOG.error(e);
    } finally {
        MsgIdHolder.clear();
    }
}
Also used : JSONObject(com.alibaba.fastjson.JSONObject) UnitRequest(info.xiancloud.core.message.UnitRequest) UnitResponse(info.xiancloud.core.message.UnitResponse) NotifyHandler(info.xiancloud.core.NotifyHandler) DefaultLocalAsyncSender(info.xiancloud.core.message.sender.local.DefaultLocalAsyncSender) MessageType(info.xiancloud.core.distribution.MessageType) RejectedExecutionException(java.util.concurrent.RejectedExecutionException)

Example 18 with UnitResponse

use of info.xiancloud.core.message.UnitResponse in project xian by happyyangyuan.

the class StreamRpcClientHandler method channelRead0.

@Override
protected void channelRead0(ChannelHandlerContext ctx, JSONObject msg) throws Exception {
    LOG.warn("已关闭此功能");
    if (MessageType.isStream(msg)) {
        try {
            StreamFragmentBean streamFragmentBean = msg.toJavaObject(StreamFragmentBean.class);
            MsgIdHolder.set(streamFragmentBean.getHeader().getMsgId());
            String ssid = streamFragmentBean.getHeader().getId();
            NotifyHandler handler = LocalNodeManager.handleMap.getIfPresent(ssid);
            LocalNodeManager.handleMap.invalidate(ssid);
            // 以下写出不会阻塞
            Stream stream = StreamManager.singleton.add(streamFragmentBean);
            if (streamFragmentBean.getHeader().isFirst()) {
                UnitResponse responseUnitResponse = UnitResponse.success(stream);
                try {
                    ThreadPoolManager.execute(() -> handler.callback(responseUnitResponse));
                } catch (RejectedExecutionException threadPoolAlreadyShutdown) {
                    LOG.info("线程池已关闭,这里使用临时线程执行任务,针对停服务时线程池已关闭的情况。");
                    new Thread(() -> handler.callback(responseUnitResponse)).start();
                }
            }
        } catch (Throwable e) {
            LOG.error(e);
        } finally {
            MsgIdHolder.clear();
        }
    } else
        ctx.fireChannelRead(msg);
}
Also used : StreamFragmentBean(info.xiancloud.core.stream.StreamFragmentBean) UnitResponse(info.xiancloud.core.message.UnitResponse) NotifyHandler(info.xiancloud.core.NotifyHandler) Stream(info.xiancloud.core.stream.Stream) RejectedExecutionException(java.util.concurrent.RejectedExecutionException)

Example 19 with UnitResponse

use of info.xiancloud.core.message.UnitResponse 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();
    }
}
Also used : Constant(info.xiancloud.core.Constant) LocalNodeManager(info.xiancloud.core.distribution.LocalNodeManager) UnitRequest(info.xiancloud.core.message.UnitRequest) NotifyHandler(info.xiancloud.core.NotifyHandler) UnitResponse(info.xiancloud.core.message.UnitResponse) ISequencer(info.xiancloud.core.sequence.ISequencer) MessageType(info.xiancloud.core.distribution.MessageType) IdManager(info.xiancloud.core.message.IdManager) DefaultLocalAsyncSender(info.xiancloud.core.message.sender.local.DefaultLocalAsyncSender) Consumer(java.util.function.Consumer) ChannelHandlerContext(io.netty.channel.ChannelHandlerContext) ThreadPoolManager(info.xiancloud.core.thread_pool.ThreadPoolManager) SimpleChannelInboundHandler(io.netty.channel.SimpleChannelInboundHandler) MsgIdHolder(info.xiancloud.core.util.thread.MsgIdHolder) JSONObject(com.alibaba.fastjson.JSONObject) LOG(info.xiancloud.core.util.LOG) UnitRequest(info.xiancloud.core.message.UnitRequest) UnitResponse(info.xiancloud.core.message.UnitResponse) NotifyHandler(info.xiancloud.core.NotifyHandler) DefaultLocalAsyncSender(info.xiancloud.core.message.sender.local.DefaultLocalAsyncSender)

Example 20 with UnitResponse

use of info.xiancloud.core.message.UnitResponse 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);
}
Also used : Group(info.xiancloud.core.Group) Unit(info.xiancloud.core.Unit) Input(info.xiancloud.core.Input) CacheConfigBean(info.xiancloud.core.support.cache.CacheConfigBean) Redis(info.xiancloud.cache.redis.Redis) UnitRequest(info.xiancloud.core.message.UnitRequest) CacheGroup(info.xiancloud.cache.service.CacheGroup) UnitResponse(info.xiancloud.core.message.UnitResponse) UnitMeta(info.xiancloud.core.UnitMeta) CacheConfigBean(info.xiancloud.core.support.cache.CacheConfigBean)

Aggregations

UnitResponse (info.xiancloud.core.message.UnitResponse)106 JSONObject (com.alibaba.fastjson.JSONObject)74 HashMap (java.util.HashMap)22 UnitRequest (info.xiancloud.core.message.UnitRequest)17 NotifyHandler (info.xiancloud.core.NotifyHandler)16 JSONArray (com.alibaba.fastjson.JSONArray)9 Unit (info.xiancloud.core.Unit)6 UnitMeta (info.xiancloud.core.UnitMeta)6 CacheGroup (info.xiancloud.cache.service.CacheGroup)5 Group (info.xiancloud.core.Group)5 Input (info.xiancloud.core.Input)5 CountDownLatch (java.util.concurrent.CountDownLatch)5 Redis (info.xiancloud.cache.redis.Redis)4 CacheConfigBean (info.xiancloud.core.support.cache.CacheConfigBean)4 ThreadPoolManager (info.xiancloud.core.thread_pool.ThreadPoolManager)3 LOG (info.xiancloud.core.util.LOG)3 Set (java.util.Set)3 Test (org.junit.Test)3 MessageType (info.xiancloud.core.distribution.MessageType)2 UnitUndefinedException (info.xiancloud.core.distribution.exception.UnitUndefinedException)2