Search in sources :

Example 1 with InvalidStreamNameException

use of com.twitter.distributedlog.exceptions.InvalidStreamNameException 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)

Example 2 with InvalidStreamNameException

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

the class TestBKDistributedLogManager method testInvalidStreamFromInvalidZkPath.

@Test(timeout = 60000)
public void testInvalidStreamFromInvalidZkPath() throws Exception {
    String baseName = testNames.getMethodName();
    String streamName = "\0blah";
    URI uri = createDLMURI("/" + baseName);
    DistributedLogNamespace namespace = DistributedLogNamespaceBuilder.newBuilder().conf(conf).uri(uri).build();
    DistributedLogManager dlm = null;
    AsyncLogWriter writer = null;
    try {
        dlm = namespace.openLog(streamName);
        writer = dlm.startAsyncLogSegmentNonPartitioned();
        fail("should have thrown");
    } catch (InvalidStreamNameException e) {
    } finally {
        if (null != writer) {
            Utils.close(writer);
        }
        if (null != dlm) {
            dlm.close();
        }
        namespace.close();
    }
}
Also used : InvalidStreamNameException(com.twitter.distributedlog.exceptions.InvalidStreamNameException) DistributedLogNamespace(com.twitter.distributedlog.namespace.DistributedLogNamespace) URI(java.net.URI) Test(org.junit.Test)

Example 3 with InvalidStreamNameException

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

the class TestBKDistributedLogNamespace method testInvalidStreamName.

@Test(timeout = 60000)
public void testInvalidStreamName() throws Exception {
    assertFalse(BKDLUtils.isReservedStreamName("test"));
    assertTrue(BKDLUtils.isReservedStreamName(".test"));
    URI uri = createDLMURI("/" + runtime.getMethodName());
    BKDistributedLogNamespace namespace = BKDistributedLogNamespace.newBuilder().conf(conf).uri(uri).build();
    try {
        namespace.openLog(".test1");
        fail("Should fail to create invalid stream .test");
    } catch (InvalidStreamNameException isne) {
    // expected
    }
    DistributedLogManager dlm = namespace.openLog("test1");
    LogWriter writer = dlm.startLogSegmentNonPartitioned();
    writer.write(DLMTestUtil.getLogRecordInstance(1));
    writer.close();
    dlm.close();
    try {
        namespace.openLog(".test2");
        fail("Should fail to create invalid stream .test2");
    } catch (InvalidStreamNameException isne) {
    // expected
    }
    try {
        namespace.openLog("/test2");
        fail("should fail to create invalid stream /test2");
    } catch (InvalidStreamNameException isne) {
    // expected
    }
    try {
        char[] chars = new char[6];
        for (int i = 0; i < chars.length; i++) {
            chars[i] = 'a';
        }
        chars[0] = 0;
        String streamName = new String(chars);
        namespace.openLog(streamName);
        fail("should fail to create invalid stream " + streamName);
    } catch (InvalidStreamNameException isne) {
    // expected
    }
    try {
        char[] chars = new char[6];
        for (int i = 0; i < chars.length; i++) {
            chars[i] = 'a';
        }
        chars[3] = '';
        String streamName = new String(chars);
        namespace.openLog(streamName);
        fail("should fail to create invalid stream " + streamName);
    } catch (InvalidStreamNameException isne) {
    // expected
    }
    DistributedLogManager newDLM = namespace.openLog("test_2-3");
    LogWriter newWriter = newDLM.startLogSegmentNonPartitioned();
    newWriter.write(DLMTestUtil.getLogRecordInstance(1));
    newWriter.close();
    newDLM.close();
    Iterator<String> streamIter = namespace.getLogs();
    Set<String> streamSet = Sets.newHashSet(streamIter);
    assertEquals(2, streamSet.size());
    assertTrue(streamSet.contains("test1"));
    assertTrue(streamSet.contains("test_2-3"));
    Map<String, byte[]> streamMetadatas = namespace.enumerateLogsWithMetadataInNamespace();
    assertEquals(2, streamMetadatas.size());
    assertTrue(streamMetadatas.containsKey("test1"));
    assertTrue(streamMetadatas.containsKey("test_2-3"));
    namespace.close();
}
Also used : InvalidStreamNameException(com.twitter.distributedlog.exceptions.InvalidStreamNameException) URI(java.net.URI) Test(org.junit.Test)

Aggregations

InvalidStreamNameException (com.twitter.distributedlog.exceptions.InvalidStreamNameException)3 URI (java.net.URI)2 Test (org.junit.Test)2 Stopwatch (com.google.common.base.Stopwatch)1 AsyncLogWriter (com.twitter.distributedlog.AsyncLogWriter)1 AlreadyClosedException (com.twitter.distributedlog.exceptions.AlreadyClosedException)1 OwnershipAcquireFailedException (com.twitter.distributedlog.exceptions.OwnershipAcquireFailedException)1 StreamUnavailableException (com.twitter.distributedlog.exceptions.StreamUnavailableException)1 DistributedLogNamespace (com.twitter.distributedlog.namespace.DistributedLogNamespace)1 FutureEventListener (com.twitter.util.FutureEventListener)1 Promise (com.twitter.util.Promise)1 ArrayDeque (java.util.ArrayDeque)1 Queue (java.util.Queue)1