Search in sources :

Example 1 with RedissonShutdownException

use of org.redisson.RedissonShutdownException 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 2 with RedissonShutdownException

use of org.redisson.RedissonShutdownException in project redisson by redisson.

the class RedisConnection method async.

public <T, R> RFuture<R> async(long timeout, Codec encoder, RedisCommand<T> command, Object... params) {
    CompletableFuture<R> promise = new CompletableFuture<>();
    if (timeout == -1) {
        timeout = redisClient.getCommandTimeout();
    }
    if (redisClient.getEventLoopGroup().isShuttingDown()) {
        RedissonShutdownException cause = new RedissonShutdownException("Redisson is shutdown");
        return RedissonPromise.newFailedFuture(cause);
    }
    Timeout scheduledFuture = redisClient.getTimer().newTimeout(t -> {
        RedisTimeoutException ex = new RedisTimeoutException("Command execution timeout for command: " + LogHelper.toString(command, params) + ", Redis client: " + redisClient);
        promise.completeExceptionally(ex);
    }, timeout, TimeUnit.MILLISECONDS);
    promise.whenComplete((res, e) -> {
        scheduledFuture.cancel();
    });
    ChannelFuture writeFuture = send(new CommandData<>(promise, encoder, command, params));
    writeFuture.addListener((ChannelFutureListener) future -> {
        if (!future.isSuccess()) {
            promise.completeExceptionally(future.cause());
        }
    });
    return new CompletableFutureWrapper<>(promise);
}
Also used : ChannelFuture(io.netty.channel.ChannelFuture) AttributeKey(io.netty.util.AttributeKey) Timeout(io.netty.util.Timeout) Logger(org.slf4j.Logger) Codec(org.redisson.client.codec.Codec) CommandsQueue(org.redisson.client.handler.CommandsQueue) org.redisson.client.protocol(org.redisson.client.protocol) RedissonPromise(org.redisson.misc.RedissonPromise) LoggerFactory(org.slf4j.LoggerFactory) TimeoutException(java.util.concurrent.TimeoutException) CompletableFuture(java.util.concurrent.CompletableFuture) Deque(java.util.Deque) RedissonShutdownException(org.redisson.RedissonShutdownException) CommandsQueuePubSub(org.redisson.client.handler.CommandsQueuePubSub) ChannelFuture(io.netty.channel.ChannelFuture) Channel(io.netty.channel.Channel) RFuture(org.redisson.api.RFuture) ExecutionException(java.util.concurrent.ExecutionException) TimeUnit(java.util.concurrent.TimeUnit) CompletableFutureWrapper(org.redisson.misc.CompletableFutureWrapper) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) ChannelFutureListener(io.netty.channel.ChannelFutureListener) Queue(java.util.Queue) LogHelper(org.redisson.misc.LogHelper) CompletableFuture(java.util.concurrent.CompletableFuture) Timeout(io.netty.util.Timeout) CompletableFutureWrapper(org.redisson.misc.CompletableFutureWrapper) RedissonShutdownException(org.redisson.RedissonShutdownException)

Example 3 with RedissonShutdownException

use of org.redisson.RedissonShutdownException in project redisson by redisson.

the class RedisExecutor method handleBlockingOperations.

private void handleBlockingOperations(CompletableFuture<R> attemptPromise, RedisConnection connection, Long popTimeout) {
    FutureListener<Void> listener = f -> {
        mainPromise.completeExceptionally(new RedissonShutdownException("Redisson is shutdown"));
    };
    Timeout scheduledFuture;
    if (popTimeout != 0) {
        // handling cases when connection has been lost
        scheduledFuture = connectionManager.newTimeout(timeout -> {
            if (attemptPromise.complete(null)) {
                connection.forceFastReconnectAsync();
            }
        }, popTimeout + 1, TimeUnit.SECONDS);
    } else {
        scheduledFuture = null;
    }
    mainPromise.whenComplete((res, e) -> {
        if (scheduledFuture != null) {
            scheduledFuture.cancel();
        }
        synchronized (listener) {
            connectionManager.getShutdownPromise().removeListener(listener);
        }
        // handling cancel operation for blocking commands
        if ((mainPromise.isCancelled() || e instanceof InterruptedException) && !attemptPromise.isDone()) {
            log.debug("Canceled blocking operation {} used {}", command, connection);
            connection.forceFastReconnectAsync().whenComplete((r, ex) -> {
                attemptPromise.cancel(true);
            });
            return;
        }
        if (e instanceof RedissonShutdownException) {
            attemptPromise.completeExceptionally(e);
        }
    });
    synchronized (listener) {
        if (!mainPromise.isDone()) {
            connectionManager.getShutdownPromise().addListener(listener);
        }
    }
}
Also used : Codec(org.redisson.client.codec.Codec) LoggerFactory(org.slf4j.LoggerFactory) RedisURI(org.redisson.misc.RedisURI) CompletableFuture(java.util.concurrent.CompletableFuture) ArrayList(java.util.ArrayList) BaseCodec(org.redisson.client.codec.BaseCodec) NodeSource(org.redisson.connection.NodeSource) ByteBuf(io.netty.buffer.ByteBuf) ScanResult(org.redisson.ScanResult) ChannelFutureListener(io.netty.channel.ChannelFutureListener) Map(java.util.Map) BiConsumer(java.util.function.BiConsumer) TimerTask(io.netty.util.TimerTask) Timeout(io.netty.util.Timeout) Logger(org.slf4j.Logger) FutureListener(io.netty.util.concurrent.FutureListener) CancellationException(java.util.concurrent.CancellationException) LRUCacheMap(org.redisson.cache.LRUCacheMap) ConnectionManager(org.redisson.connection.ConnectionManager) org.redisson.client(org.redisson.client) CommandData(org.redisson.client.protocol.CommandData) CompletionException(java.util.concurrent.CompletionException) Redirect(org.redisson.connection.NodeSource.Redirect) RedissonShutdownException(org.redisson.RedissonShutdownException) ChannelFuture(io.netty.channel.ChannelFuture) RedisCommands(org.redisson.client.protocol.RedisCommands) TimeUnit(java.util.concurrent.TimeUnit) List(java.util.List) ReferenceCountUtil(io.netty.util.ReferenceCountUtil) RedisCommand(org.redisson.client.protocol.RedisCommand) RedissonObjectBuilder(org.redisson.liveobject.core.RedissonObjectBuilder) CommandsData(org.redisson.client.protocol.CommandsData) LogHelper(org.redisson.misc.LogHelper) Timeout(io.netty.util.Timeout) RedissonShutdownException(org.redisson.RedissonShutdownException)

Example 4 with RedissonShutdownException

use of org.redisson.RedissonShutdownException in project redisson by redisson.

the class RedissonExecutorRemoteService method invokeMethod.

@Override
protected <T> void invokeMethod(RemoteServiceRequest request, RemoteServiceMethod method, CompletableFuture<RemoteServiceCancelRequest> cancelRequestFuture, CompletableFuture<RRemoteServiceResponse> responsePromise) {
    startedListeners.forEach(l -> l.onStarted(request.getId()));
    if (taskTimeout > 0) {
        commandExecutor.getConnectionManager().getGroup().schedule(() -> {
            cancelRequestFuture.complete(new RemoteServiceCancelRequest(true, false));
        }, taskTimeout, TimeUnit.MILLISECONDS);
    }
    try {
        Object result = method.getMethod().invoke(method.getBean(), request.getArgs());
        RemoteServiceResponse response = new RemoteServiceResponse(request.getId(), result);
        responsePromise.complete(response);
    } catch (Exception e) {
        if (e instanceof InvocationTargetException && e.getCause() instanceof RedissonShutdownException) {
            if (cancelRequestFuture != null) {
                cancelRequestFuture.cancel(false);
            }
            return;
        }
        RemoteServiceResponse response = new RemoteServiceResponse(request.getId(), e.getCause());
        responsePromise.complete(response);
        log.error("Can't execute: " + request, e);
    }
    if (cancelRequestFuture != null) {
        cancelRequestFuture.cancel(false);
    }
    if (commandExecutor.getNow(responsePromise) instanceof RemoteServiceResponse) {
        RemoteServiceResponse response = (RemoteServiceResponse) commandExecutor.getNow(responsePromise);
        if (response.getError() == null) {
            successListeners.forEach(l -> l.onSucceeded(request.getId(), response.getResult()));
        } else {
            failureListeners.forEach(l -> l.onFailed(request.getId(), response.getError()));
        }
    } else {
        failureListeners.forEach(l -> l.onFailed(request.getId(), null));
    }
    finishedListeners.forEach(l -> l.onFinished(request.getId()));
}
Also used : RedissonObject(org.redisson.RedissonObject) RedissonShutdownException(org.redisson.RedissonShutdownException) RedissonShutdownException(org.redisson.RedissonShutdownException) InvocationTargetException(java.lang.reflect.InvocationTargetException) InvocationTargetException(java.lang.reflect.InvocationTargetException)

Example 5 with RedissonShutdownException

use of org.redisson.RedissonShutdownException in project redisson by redisson.

the class CommandAsyncService method async.

protected <V, R> void async(final boolean readOnlyMode, final NodeSource source, final Codec codec, final RedisCommand<V> command, final Object[] params, final RPromise<R> mainPromise, final int attempt) {
    if (mainPromise.isCancelled()) {
        return;
    }
    if (!connectionManager.getShutdownLatch().acquire()) {
        mainPromise.tryFailure(new RedissonShutdownException("Redisson is shutdown"));
        return;
    }
    final AsyncDetails<V, R> details = AsyncDetails.acquire();
    if (isRedissonReferenceSupportEnabled()) {
        try {
            for (int i = 0; i < params.length; i++) {
                RedissonReference reference = redisson != null ? RedissonObjectFactory.toReference(redisson, params[i]) : RedissonObjectFactory.toReference(redissonReactive, params[i]);
                params[i] = reference == null ? params[i] : reference;
            }
        } catch (Exception e) {
            connectionManager.getShutdownLatch().release();
            mainPromise.tryFailure(e);
            return;
        }
    }
    final RFuture<RedisConnection> connectionFuture;
    if (readOnlyMode) {
        connectionFuture = connectionManager.connectionReadOp(source, command);
    } else {
        connectionFuture = connectionManager.connectionWriteOp(source, command);
    }
    final RPromise<R> attemptPromise = connectionManager.newPromise();
    details.init(connectionFuture, attemptPromise, readOnlyMode, source, codec, command, params, mainPromise, attempt);
    final TimerTask retryTimerTask = new TimerTask() {

        @Override
        public void run(Timeout t) throws Exception {
            if (details.getAttemptPromise().isDone()) {
                return;
            }
            if (details.getConnectionFuture().cancel(false)) {
                connectionManager.getShutdownLatch().release();
            } else {
                if (details.getConnectionFuture().isSuccess()) {
                    ChannelFuture writeFuture = details.getWriteFuture();
                    if (writeFuture != null && !writeFuture.cancel(false) && writeFuture.isSuccess()) {
                        return;
                    }
                }
            }
            if (details.getMainPromise().isCancelled()) {
                if (details.getAttemptPromise().cancel(false)) {
                    AsyncDetails.release(details);
                }
                return;
            }
            if (details.getAttempt() == connectionManager.getConfig().getRetryAttempts()) {
                if (details.getException() == null) {
                    details.setException(new RedisTimeoutException("Command execution timeout for command: " + command + " with params: " + LogHelper.toString(details.getParams())));
                }
                details.getAttemptPromise().tryFailure(details.getException());
                return;
            }
            if (!details.getAttemptPromise().cancel(false)) {
                return;
            }
            int count = details.getAttempt() + 1;
            if (log.isDebugEnabled()) {
                log.debug("attempt {} for command {} and params {}", count, details.getCommand(), Arrays.toString(details.getParams()));
            }
            async(details.isReadOnlyMode(), details.getSource(), details.getCodec(), details.getCommand(), details.getParams(), details.getMainPromise(), count);
            AsyncDetails.release(details);
        }
    };
    Timeout timeout = connectionManager.newTimeout(retryTimerTask, connectionManager.getConfig().getRetryInterval(), TimeUnit.MILLISECONDS);
    details.setTimeout(timeout);
    connectionFuture.addListener(new FutureListener<RedisConnection>() {

        @Override
        public void operationComplete(Future<RedisConnection> connFuture) throws Exception {
            if (connFuture.isCancelled()) {
                return;
            }
            if (!connFuture.isSuccess()) {
                connectionManager.getShutdownLatch().release();
                details.setException(convertException(connectionFuture));
                return;
            }
            if (details.getAttemptPromise().isDone() || details.getMainPromise().isDone()) {
                releaseConnection(source, connectionFuture, details.isReadOnlyMode(), details.getAttemptPromise(), details);
                return;
            }
            final RedisConnection connection = connFuture.getNow();
            if (details.getSource().getRedirect() == Redirect.ASK) {
                List<CommandData<?, ?>> list = new ArrayList<CommandData<?, ?>>(2);
                RPromise<Void> promise = connectionManager.newPromise();
                list.add(new CommandData<Void, Void>(promise, details.getCodec(), RedisCommands.ASKING, new Object[] {}));
                list.add(new CommandData<V, R>(details.getAttemptPromise(), details.getCodec(), details.getCommand(), details.getParams()));
                RPromise<Void> main = connectionManager.newPromise();
                ChannelFuture future = connection.send(new CommandsData(main, list));
                details.setWriteFuture(future);
            } else {
                if (log.isDebugEnabled()) {
                    log.debug("aquired connection for command {} and params {} from slot {} using node {}", details.getCommand(), Arrays.toString(details.getParams()), details.getSource(), connection.getRedisClient().getAddr());
                }
                ChannelFuture future = connection.send(new CommandData<V, R>(details.getAttemptPromise(), details.getCodec(), details.getCommand(), details.getParams()));
                details.setWriteFuture(future);
            }
            details.getWriteFuture().addListener(new ChannelFutureListener() {

                @Override
                public void operationComplete(ChannelFuture future) throws Exception {
                    checkWriteFuture(details, connection);
                }
            });
            releaseConnection(source, connectionFuture, details.isReadOnlyMode(), details.getAttemptPromise(), details);
        }
    });
    attemptPromise.addListener(new FutureListener<R>() {

        @Override
        public void operationComplete(Future<R> future) throws Exception {
            checkAttemptFuture(source, details, future);
        }
    });
}
Also used : RPromise(org.redisson.misc.RPromise) TimerTask(io.netty.util.TimerTask) List(java.util.List) ArrayList(java.util.ArrayList) CommandsData(org.redisson.client.protocol.CommandsData) ChannelFuture(io.netty.channel.ChannelFuture) RedissonReference(org.redisson.RedissonReference) Timeout(io.netty.util.Timeout) ChannelFutureListener(io.netty.channel.ChannelFutureListener) 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) RedisTimeoutException(org.redisson.client.RedisTimeoutException) RedissonShutdownException(org.redisson.RedissonShutdownException) CommandData(org.redisson.client.protocol.CommandData) RedisConnection(org.redisson.client.RedisConnection)

Aggregations

RedissonShutdownException (org.redisson.RedissonShutdownException)6 ChannelFuture (io.netty.channel.ChannelFuture)5 ChannelFutureListener (io.netty.channel.ChannelFutureListener)5 Timeout (io.netty.util.Timeout)4 TimerTask (io.netty.util.TimerTask)3 CompletableFuture (java.util.concurrent.CompletableFuture)3 Channel (io.netty.channel.Channel)2 FutureListener (io.netty.util.concurrent.FutureListener)2 ArrayList (java.util.ArrayList)2 List (java.util.List)2 CancellationException (java.util.concurrent.CancellationException)2 CompletionException (java.util.concurrent.CompletionException)2 TimeUnit (java.util.concurrent.TimeUnit)2 RFuture (org.redisson.api.RFuture)2 RedisAskException (org.redisson.client.RedisAskException)2 RedisException (org.redisson.client.RedisException)2 RedisLoadingException (org.redisson.client.RedisLoadingException)2 RedisMovedException (org.redisson.client.RedisMovedException)2 RedisTimeoutException (org.redisson.client.RedisTimeoutException)2 Codec (org.redisson.client.codec.Codec)2