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;
}
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();
}
}
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();
}
Aggregations