Search in sources :

Example 1 with AlreadyClosedException

use of com.twitter.distributedlog.exceptions.AlreadyClosedException in project distributedlog by twitter.

the class StreamImpl method doExecuteOp.

private void doExecuteOp(final StreamOp op, boolean success) {
    final AsyncLogWriter writer;
    final Throwable lastException;
    synchronized (this) {
        writer = this.writer;
        lastException = this.lastException;
    }
    if (null != writer && success) {
        op.execute(writer, sequencer, txnLock).addEventListener(new FutureEventListener<Void>() {

            @Override
            public void onSuccess(Void value) {
            // nop
            }

            @Override
            public void onFailure(Throwable cause) {
                boolean countAsException = true;
                if (cause instanceof DLException) {
                    final DLException dle = (DLException) cause;
                    switch(dle.getCode()) {
                        case FOUND:
                            assert (cause instanceof OwnershipAcquireFailedException);
                            countAsException = false;
                            handleOwnershipAcquireFailedException(op, (OwnershipAcquireFailedException) cause);
                            break;
                        case ALREADY_CLOSED:
                            assert (cause instanceof AlreadyClosedException);
                            op.fail(cause);
                            handleAlreadyClosedException((AlreadyClosedException) cause);
                            break;
                        // exceptions that mostly from client (e.g. too large record)
                        case NOT_IMPLEMENTED:
                        case METADATA_EXCEPTION:
                        case LOG_EMPTY:
                        case LOG_NOT_FOUND:
                        case TRUNCATED_TRANSACTION:
                        case END_OF_STREAM:
                        case TRANSACTION_OUT_OF_ORDER:
                        case INVALID_STREAM_NAME:
                        case TOO_LARGE_RECORD:
                        case STREAM_NOT_READY:
                        case OVER_CAPACITY:
                            op.fail(cause);
                            break;
                        // exceptions that *could* / *might* be recovered by creating a new writer
                        default:
                            handleRecoverableDLException(op, cause);
                            break;
                    }
                } else {
                    handleUnknownException(op, cause);
                }
                if (countAsException) {
                    countException(cause, streamExceptionStatLogger);
                }
            }
        });
    } else {
        op.fail(lastException);
    }
}
Also used : OwnershipAcquireFailedException(com.twitter.distributedlog.exceptions.OwnershipAcquireFailedException) DLException(com.twitter.distributedlog.exceptions.DLException) AsyncLogWriter(com.twitter.distributedlog.AsyncLogWriter) AlreadyClosedException(com.twitter.distributedlog.exceptions.AlreadyClosedException)

Example 2 with AlreadyClosedException

use of com.twitter.distributedlog.exceptions.AlreadyClosedException in project distributedlog by twitter.

the class StreamImpl method acquireStream.

Future<Boolean> acquireStream() {
    // Reset this flag so the acquire thread knows whether re-acquire is needed.
    writeSinceLastAcquire = false;
    final Stopwatch stopwatch = Stopwatch.createStarted();
    final Promise<Boolean> acquirePromise = new Promise<Boolean>();
    manager.openAsyncLogWriter().addEventListener(FutureUtils.OrderedFutureEventListener.of(new FutureEventListener<AsyncLogWriter>() {

        @Override
        public void onSuccess(AsyncLogWriter w) {
            synchronized (txnLock) {
                sequencer.setLastId(w.getLastTxId());
            }
            AsyncLogWriter oldWriter;
            Queue<StreamOp> oldPendingOps;
            boolean success;
            synchronized (StreamImpl.this) {
                oldWriter = setStreamStatus(StreamStatus.INITIALIZED, StreamStatus.INITIALIZING, w, null, null);
                oldPendingOps = pendingOps;
                pendingOps = new ArrayDeque<StreamOp>();
                success = true;
            }
            // check if the stream is allowed to be acquired
            if (!streamManager.allowAcquire(StreamImpl.this)) {
                if (null != oldWriter) {
                    Abortables.asyncAbort(oldWriter, true);
                }
                int maxAcquiredPartitions = dynConf.getMaxAcquiredPartitionsPerProxy();
                StreamUnavailableException sue = new StreamUnavailableException("Stream " + partition.getStream() + " is not allowed to acquire more than " + maxAcquiredPartitions + " partitions");
                countException(sue, exceptionStatLogger);
                logger.error("Failed to acquire stream {} because it is unavailable : {}", name, sue.getMessage());
                synchronized (this) {
                    oldWriter = setStreamStatus(StreamStatus.ERROR, StreamStatus.INITIALIZED, null, null, sue);
                    // we don't switch the pending ops since they are already switched
                    // when setting the status to initialized
                    success = false;
                }
            }
            processPendingRequestsAfterOpen(success, oldWriter, oldPendingOps);
        }

        @Override
        public void onFailure(Throwable cause) {
            AsyncLogWriter oldWriter;
            Queue<StreamOp> oldPendingOps;
            boolean success;
            if (cause instanceof AlreadyClosedException) {
                countException(cause, streamExceptionStatLogger);
                handleAlreadyClosedException((AlreadyClosedException) cause);
                return;
            } else if (cause instanceof OwnershipAcquireFailedException) {
                OwnershipAcquireFailedException oafe = (OwnershipAcquireFailedException) cause;
                logger.warn("Failed to acquire stream ownership for {}, current owner is {} : {}", new Object[] { name, oafe.getCurrentOwner(), oafe.getMessage() });
                synchronized (StreamImpl.this) {
                    oldWriter = setStreamStatus(StreamStatus.BACKOFF, StreamStatus.INITIALIZING, null, oafe.getCurrentOwner(), oafe);
                    oldPendingOps = pendingOps;
                    pendingOps = new ArrayDeque<StreamOp>();
                    success = false;
                }
            } else if (cause instanceof InvalidStreamNameException) {
                InvalidStreamNameException isne = (InvalidStreamNameException) cause;
                countException(isne, streamExceptionStatLogger);
                logger.error("Failed to acquire stream {} due to its name is invalid", name);
                synchronized (StreamImpl.this) {
                    oldWriter = setStreamStatus(StreamStatus.ERROR, StreamStatus.INITIALIZING, null, null, isne);
                    oldPendingOps = pendingOps;
                    pendingOps = new ArrayDeque<StreamOp>();
                    success = false;
                }
            } else {
                countException(cause, streamExceptionStatLogger);
                logger.error("Failed to initialize stream {} : ", name, cause);
                synchronized (StreamImpl.this) {
                    oldWriter = setStreamStatus(StreamStatus.FAILED, StreamStatus.INITIALIZING, null, null, cause);
                    oldPendingOps = pendingOps;
                    pendingOps = new ArrayDeque<StreamOp>();
                    success = false;
                }
            }
            processPendingRequestsAfterOpen(success, oldWriter, oldPendingOps);
        }

        void processPendingRequestsAfterOpen(boolean success, AsyncLogWriter oldWriter, Queue<StreamOp> oldPendingOps) {
            if (success) {
                streamAcquireStat.registerSuccessfulEvent(stopwatch.elapsed(TimeUnit.MICROSECONDS));
            } else {
                streamAcquireStat.registerFailedEvent(stopwatch.elapsed(TimeUnit.MICROSECONDS));
            }
            for (StreamOp op : oldPendingOps) {
                executeOp(op, success);
                pendingOpsCounter.dec();
            }
            Abortables.asyncAbort(oldWriter, true);
            FutureUtils.setValue(acquirePromise, success);
        }
    }, scheduler, getStreamName()));
    return acquirePromise;
}
Also used : StreamUnavailableException(com.twitter.distributedlog.exceptions.StreamUnavailableException) OwnershipAcquireFailedException(com.twitter.distributedlog.exceptions.OwnershipAcquireFailedException) InvalidStreamNameException(com.twitter.distributedlog.exceptions.InvalidStreamNameException) Stopwatch(com.google.common.base.Stopwatch) AsyncLogWriter(com.twitter.distributedlog.AsyncLogWriter) AlreadyClosedException(com.twitter.distributedlog.exceptions.AlreadyClosedException) ArrayDeque(java.util.ArrayDeque) Promise(com.twitter.util.Promise) FutureEventListener(com.twitter.util.FutureEventListener) Queue(java.util.Queue)

Aggregations

AsyncLogWriter (com.twitter.distributedlog.AsyncLogWriter)2 AlreadyClosedException (com.twitter.distributedlog.exceptions.AlreadyClosedException)2 OwnershipAcquireFailedException (com.twitter.distributedlog.exceptions.OwnershipAcquireFailedException)2 Stopwatch (com.google.common.base.Stopwatch)1 DLException (com.twitter.distributedlog.exceptions.DLException)1 InvalidStreamNameException (com.twitter.distributedlog.exceptions.InvalidStreamNameException)1 StreamUnavailableException (com.twitter.distributedlog.exceptions.StreamUnavailableException)1 FutureEventListener (com.twitter.util.FutureEventListener)1 Promise (com.twitter.util.Promise)1 ArrayDeque (java.util.ArrayDeque)1 Queue (java.util.Queue)1