Search in sources :

Example 11 with TimerTask

use of io.netty.util.TimerTask in project redisson by redisson.

the class CommandAsyncService method handleBlockingOperations.

private <R, V> void handleBlockingOperations(final AsyncDetails<V, R> details, final RedisConnection connection, Long popTimeout) {
    final FutureListener<Boolean> listener = new FutureListener<Boolean>() {

        @Override
        public void operationComplete(Future<Boolean> future) throws Exception {
            details.getMainPromise().tryFailure(new RedissonShutdownException("Redisson is shutdown"));
        }
    };
    final AtomicBoolean canceledByScheduler = new AtomicBoolean();
    final Timeout scheduledFuture;
    if (popTimeout != 0) {
        // to handle cases when connection has been lost
        final Channel orignalChannel = connection.getChannel();
        scheduledFuture = connectionManager.newTimeout(new TimerTask() {

            @Override
            public void run(Timeout timeout) throws Exception {
                // and connection is still active
                if (orignalChannel == connection.getChannel() && connection.isActive()) {
                    return;
                }
                canceledByScheduler.set(true);
                details.getAttemptPromise().trySuccess(null);
            }
        }, popTimeout, TimeUnit.SECONDS);
    } else {
        scheduledFuture = null;
    }
    details.getMainPromise().addListener(new FutureListener<R>() {

        @Override
        public void operationComplete(Future<R> future) throws Exception {
            if (scheduledFuture != null) {
                scheduledFuture.cancel();
            }
            synchronized (listener) {
                connectionManager.getShutdownPromise().removeListener(listener);
            }
            // handling cancel operation for commands from skipTimeout collection
            if ((future.isCancelled() && details.getAttemptPromise().cancel(true)) || canceledByScheduler.get()) {
                connection.forceFastReconnectAsync();
                return;
            }
            if (future.cause() instanceof RedissonShutdownException) {
                details.getAttemptPromise().tryFailure(future.cause());
            }
        }
    });
    synchronized (listener) {
        if (!details.getMainPromise().isDone()) {
            connectionManager.getShutdownPromise().addListener(listener);
        }
    }
}
Also used : FutureListener(io.netty.util.concurrent.FutureListener) ChannelFutureListener(io.netty.channel.ChannelFutureListener) Timeout(io.netty.util.Timeout) Channel(io.netty.channel.Channel) RedisAskException(org.redisson.client.RedisAskException) RedisLoadingException(org.redisson.client.RedisLoadingException) RedisTimeoutException(org.redisson.client.RedisTimeoutException) RedisException(org.redisson.client.RedisException) RedisMovedException(org.redisson.client.RedisMovedException) WriteRedisConnectionException(org.redisson.client.WriteRedisConnectionException) RedisTryAgainException(org.redisson.client.RedisTryAgainException) RedissonShutdownException(org.redisson.RedissonShutdownException) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) TimerTask(io.netty.util.TimerTask) RFuture(org.redisson.api.RFuture) ChannelFuture(io.netty.channel.ChannelFuture) Future(io.netty.util.concurrent.Future) RedissonShutdownException(org.redisson.RedissonShutdownException) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean)

Example 12 with TimerTask

use of io.netty.util.TimerTask in project redisson by redisson.

the class CommandAsyncService method checkWriteFuture.

private <V, R> void checkWriteFuture(final AsyncDetails<V, R> details, final RedisConnection connection) {
    ChannelFuture future = details.getWriteFuture();
    if (details.getAttemptPromise().isDone() || future.isCancelled()) {
        return;
    }
    if (!future.isSuccess()) {
        details.setException(new WriteRedisConnectionException("Can't write command: " + details.getCommand() + ", params: " + LogHelper.toString(details.getParams()) + " to channel: " + future.channel(), future.cause()));
        return;
    }
    details.getTimeout().cancel();
    long timeoutTime = connectionManager.getConfig().getTimeout();
    if (RedisCommands.BLOCKING_COMMANDS.contains(details.getCommand().getName())) {
        Long popTimeout = Long.valueOf(details.getParams()[details.getParams().length - 1].toString());
        handleBlockingOperations(details, connection, popTimeout);
        if (popTimeout == 0) {
            return;
        }
        timeoutTime += popTimeout * 1000;
        // add 1 second due to issue https://github.com/antirez/redis/issues/874
        timeoutTime += 1000;
    }
    final long timeoutAmount = timeoutTime;
    TimerTask timeoutTask = new TimerTask() {

        @Override
        public void run(Timeout timeout) throws Exception {
            details.getAttemptPromise().tryFailure(new RedisTimeoutException("Redis server response timeout (" + timeoutAmount + " ms) occured for command: " + details.getCommand() + " with params: " + LogHelper.toString(details.getParams()) + " channel: " + connection.getChannel()));
        }
    };
    Timeout timeout = connectionManager.newTimeout(timeoutTask, timeoutTime, TimeUnit.MILLISECONDS);
    details.setTimeout(timeout);
}
Also used : ChannelFuture(io.netty.channel.ChannelFuture) WriteRedisConnectionException(org.redisson.client.WriteRedisConnectionException) TimerTask(io.netty.util.TimerTask) RedisTimeoutException(org.redisson.client.RedisTimeoutException) Timeout(io.netty.util.Timeout)

Example 13 with TimerTask

use of io.netty.util.TimerTask in project redisson by redisson.

the class ConnectionWatchdog method reconnect.

private void reconnect(final RedisConnection connection, final int attempts) {
    int timeout = 2 << attempts;
    if (bootstrap.group().isShuttingDown()) {
        return;
    }
    timer.newTimeout(new TimerTask() {

        @Override
        public void run(Timeout timeout) throws Exception {
            tryReconnect(connection, Math.min(BACKOFF_CAP, attempts + 1));
        }
    }, timeout, TimeUnit.MILLISECONDS);
}
Also used : TimerTask(io.netty.util.TimerTask) Timeout(io.netty.util.Timeout) RedisException(org.redisson.client.RedisException)

Example 14 with TimerTask

use of io.netty.util.TimerTask in project web3sdk by FISCO-BCOS.

the class Service method asyncSendChannelMessage.

public void asyncSendChannelMessage(ChannelRequest request, ChannelResponseCallback callback) {
    try {
        logger.debug("处理链上链下请求: " + request.getMessageID());
        callback.setService(this);
        ChannelMessage channelMessage = new ChannelMessage();
        channelMessage.setSeq(request.getMessageID());
        channelMessage.setResult(0);
        // 链上链下请求0x20
        channelMessage.setType((short) 0x20);
        channelMessage.setData(request.getContent().getBytes());
        try {
            List<ConnectionInfo> fromConnectionInfos = new ArrayList<ConnectionInfo>();
            List<ConnectionInfo> toConnectionInfos = new ArrayList<ConnectionInfo>();
            // 设置发送节点
            ChannelConnections fromChannelConnections = allChannelConnections.get(orgID);
            if (fromChannelConnections == null) {
                // 没有找到对应的链
                // 返回错误
                logger.error("没有找到本机构:{}", request.getFromOrg());
                throw new Exception("未找到本机构");
            }
            fromConnectionInfos.addAll(fromChannelConnections.getConnections());
            logger.debug("发送结构:{} 节点数:{}", request.getFromOrg(), fromChannelConnections.getConnections().size());
            callback.setFromChannelConnections(fromChannelConnections);
            callback.setFromConnectionInfos(fromConnectionInfos);
            // 设置目的节点
            ChannelConnections toChannelConnections = allChannelConnections.get(request.getToOrg());
            if (toChannelConnections == null) {
                logger.error("未找到目的机构: {}", request.getToOrg());
                throw new Exception("未找到目标机构");
            }
            toConnectionInfos.addAll(toChannelConnections.getConnections());
            logger.debug("机构:{} 节点数:{}", request.getToOrg(), toChannelConnections.getConnections().size());
            callback.setToConnectionInfos(toConnectionInfos);
            // 设置消息内容
            callback.setRequest(channelMessage);
            seq2Callback.put(request.getMessageID(), callback);
            if (request.getTimeout() > 0) {
                final ChannelResponseCallback callbackInner = callback;
                callback.setTimeout(timeoutHandler.newTimeout(new TimerTask() {

                    ChannelResponseCallback _callback = callbackInner;

                    @Override
                    public void run(Timeout timeout) throws Exception {
                        // 处理超时逻辑
                        _callback.onTimeout();
                    }
                }, request.getTimeout(), TimeUnit.MILLISECONDS));
            }
            callback.retrySendMessage(0);
        } catch (Exception e) {
            logger.error("发送消息异常 消息未发出", e);
            ChannelResponse response = new ChannelResponse();
            response.setErrorCode(100);
            response.setMessageID(request.getMessageID());
            response.setErrorMessage(e.getMessage());
            response.setContent("");
            callback.onResponse(response);
            return;
        }
    } catch (Exception e) {
        logger.error("系统错误", e);
    }
}
Also used : ChannelConnections(org.bcos.channel.handler.ChannelConnections) TimerTask(io.netty.util.TimerTask) Timeout(io.netty.util.Timeout) ArrayList(java.util.ArrayList) ConnectionInfo(org.bcos.channel.handler.ConnectionInfo) ChannelResponse(org.bcos.channel.dto.ChannelResponse) UnsupportedEncodingException(java.io.UnsupportedEncodingException) ChannelMessage(org.bcos.channel.dto.ChannelMessage)

Example 15 with TimerTask

use of io.netty.util.TimerTask in project web3sdk by FISCO-BCOS.

the class Service method asyncSendEthereumMessage.

public void asyncSendEthereumMessage(EthereumRequest request, EthereumResponseCallback callback) {
    logger.debug("处理Ethereum请求: " + request.getMessageID());
    Boolean sended = false;
    EthereumMessage ethereumMessage = new EthereumMessage();
    ethereumMessage.setSeq(request.getMessageID());
    ethereumMessage.setResult(0);
    ethereumMessage.setType((short) 0x12);
    ethereumMessage.setData(request.getContent().getBytes());
    // 选取发送节点
    try {
        ChannelConnections fromChannelConnections = allChannelConnections.get(orgID);
        if (fromChannelConnections == null) {
            // 没有找到对应的链
            // 返回错误
            logger.error("没有找到本机构:{}", orgID);
            throw new Exception("未找到本机构");
        }
        ChannelHandlerContext ctx = fromChannelConnections.randomNetworkConnection();
        ByteBuf out = ctx.alloc().buffer();
        ethereumMessage.writeHeader(out);
        ethereumMessage.writeExtra(out);
        seq2Callback.put(request.getMessageID(), callback);
        if (request.getTimeout() > 0) {
            // ethereum名字可能会搞混,换成channel
            final EthereumResponseCallback callbackInner = callback;
            callback.setTimeout(timeoutHandler.newTimeout(new TimerTask() {

                EthereumResponseCallback _callback = callbackInner;

                @Override
                public void run(Timeout timeout) throws Exception {
                    // 处理超时逻辑
                    _callback.onTimeout();
                }
            }, request.getTimeout(), TimeUnit.MILLISECONDS));
        }
        ctx.writeAndFlush(out);
        logger.debug("发送Ethereum消息至 " + ((SocketChannel) ctx.channel()).remoteAddress().getAddress().getHostAddress() + ":" + ((SocketChannel) ctx.channel()).remoteAddress().getPort() + " 成功");
        sended = true;
    } catch (Exception e) {
        logger.error("系统错误", e);
        EthereumResponse response = new EthereumResponse();
        response.setErrorCode(-1);
        response.setErrorMessage("系统错误");
        response.setContent("");
        response.setMessageID(request.getMessageID());
        if (callback.getTimeout() != null) {
            callback.getTimeout().cancel();
        }
        callback.onResponse(response);
    }
}
Also used : ChannelConnections(org.bcos.channel.handler.ChannelConnections) SocketChannel(io.netty.channel.socket.SocketChannel) TimerTask(io.netty.util.TimerTask) Timeout(io.netty.util.Timeout) ChannelHandlerContext(io.netty.channel.ChannelHandlerContext) ByteBuf(io.netty.buffer.ByteBuf) EthereumResponse(org.bcos.channel.dto.EthereumResponse) UnsupportedEncodingException(java.io.UnsupportedEncodingException) EthereumMessage(org.bcos.channel.dto.EthereumMessage)

Aggregations

Timeout (io.netty.util.Timeout)38 TimerTask (io.netty.util.TimerTask)38 AtomicReference (java.util.concurrent.atomic.AtomicReference)13 AtomicBoolean (java.util.concurrent.atomic.AtomicBoolean)11 AtomicLong (java.util.concurrent.atomic.AtomicLong)8 RFuture (org.redisson.api.RFuture)8 RedisTimeoutException (org.redisson.client.RedisTimeoutException)7 FutureListener (io.netty.util.concurrent.FutureListener)6 ByteBuf (io.netty.buffer.ByteBuf)5 ChannelFuture (io.netty.channel.ChannelFuture)5 Future (io.netty.util.concurrent.Future)5 UnsupportedEncodingException (java.io.UnsupportedEncodingException)5 ArrayList (java.util.ArrayList)5 RedisException (org.redisson.client.RedisException)5 WriteRedisConnectionException (org.redisson.client.WriteRedisConnectionException)5 CompletableFutureWrapper (org.redisson.misc.CompletableFutureWrapper)5 RedisConnection (org.redisson.client.RedisConnection)4 JsonProcessingException (com.fasterxml.jackson.core.JsonProcessingException)3 ChannelFutureListener (io.netty.channel.ChannelFutureListener)3 IOException (java.io.IOException)3