use of com.twitter.util.Promise in project distributedlog by twitter.
the class BKDistributedLogManager method asyncCreateWriteHandler.
Future<BKLogWriteHandler> asyncCreateWriteHandler(final boolean lockHandler) {
final ZooKeeper zk;
try {
zk = writerZKC.get();
} catch (InterruptedException e) {
LOG.error("Failed to initialize zookeeper client : ", e);
return Future.exception(new DLInterruptedException("Failed to initialize zookeeper client", e));
} catch (ZooKeeperClient.ZooKeeperConnectionException e) {
return Future.exception(FutureUtils.zkException(e, uri.getPath()));
}
boolean ownAllocator = null == ledgerAllocator;
// Fetching Log Metadata
Future<ZKLogMetadataForWriter> metadataFuture = ZKLogMetadataForWriter.of(uri, name, streamIdentifier, zk, writerZKC.getDefaultACL(), ownAllocator, conf.getCreateStreamIfNotExists() || ownAllocator);
return metadataFuture.flatMap(new AbstractFunction1<ZKLogMetadataForWriter, Future<BKLogWriteHandler>>() {
@Override
public Future<BKLogWriteHandler> apply(ZKLogMetadataForWriter logMetadata) {
Promise<BKLogWriteHandler> createPromise = new Promise<BKLogWriteHandler>();
createWriteHandler(logMetadata, lockHandler, createPromise);
return createPromise;
}
});
}
use of com.twitter.util.Promise in project distributedlog by twitter.
the class DistributedLogMultiStreamWriter method write.
public synchronized Future<DLSN> write(ByteBuffer buffer) {
int logRecordSize = buffer.remaining();
if (logRecordSize > MAX_LOGRECORD_SIZE) {
return Future.exception(new LogRecordTooLongException("Log record of size " + logRecordSize + " written when only " + MAX_LOGRECORD_SIZE + " is allowed"));
}
// if exceed max number of bytes
if ((recordSetWriter.getNumBytes() + logRecordSize) > MAX_LOGRECORDSET_SIZE) {
flush();
}
Promise<DLSN> writePromise = new Promise<DLSN>();
try {
recordSetWriter.writeRecord(buffer, writePromise);
} catch (LogRecordTooLongException e) {
return Future.exception(e);
} catch (WriteException e) {
recordSetWriter.abortTransmit(e);
recordSetWriter = newRecordSetWriter();
return Future.exception(e);
}
if (recordSetWriter.getNumBytes() >= bufferSize) {
flush();
}
return writePromise;
}
use of com.twitter.util.Promise in project distributedlog by twitter.
the class AtomicWriter method main.
public static void main(String[] args) throws Exception {
if (args.length < 3) {
System.out.println(HELP);
return;
}
String finagleNameStr = args[0];
String streamName = args[1];
String[] messages = new String[args.length - 2];
System.arraycopy(args, 2, messages, 0, messages.length);
DistributedLogClient client = DistributedLogClientBuilder.newBuilder().clientId(ClientId$.MODULE$.apply("atomic-writer")).name("atomic-writer").thriftmux(true).finagleNameStr(finagleNameStr).build();
final LogRecordSet.Writer recordSetWriter = LogRecordSet.newWriter(16 * 1024, Type.NONE);
List<Future<DLSN>> writeFutures = Lists.newArrayListWithExpectedSize(messages.length);
for (String msg : messages) {
final String message = msg;
ByteBuffer msgBuf = ByteBuffer.wrap(msg.getBytes(UTF_8));
Promise<DLSN> writeFuture = new Promise<DLSN>();
writeFuture.addEventListener(new FutureEventListener<DLSN>() {
@Override
public void onFailure(Throwable cause) {
System.out.println("Encountered error on writing data");
cause.printStackTrace(System.err);
Runtime.getRuntime().exit(0);
}
@Override
public void onSuccess(DLSN dlsn) {
System.out.println("Write '" + message + "' as record " + dlsn);
}
});
recordSetWriter.writeRecord(msgBuf, writeFuture);
writeFutures.add(writeFuture);
}
FutureUtils.result(client.writeRecordSet(streamName, recordSetWriter).addEventListener(new FutureEventListener<DLSN>() {
@Override
public void onFailure(Throwable cause) {
recordSetWriter.abortTransmit(cause);
System.out.println("Encountered error on writing data");
cause.printStackTrace(System.err);
Runtime.getRuntime().exit(0);
}
@Override
public void onSuccess(DLSN dlsn) {
recordSetWriter.completeTransmit(dlsn.getLogSegmentSequenceNo(), dlsn.getEntryId(), dlsn.getSlotId());
}
}));
FutureUtils.result(Future.collect(writeFutures));
client.close();
}
use of com.twitter.util.Promise 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.util.Promise in project distributedlog by twitter.
the class StreamManagerImpl method closeAndRemoveAsync.
/**
* Must be enqueued to an executor to avoid deadlocks (close and execute-op both
* try to acquire the same read-write lock).
*/
@Override
public Future<Void> closeAndRemoveAsync(final String streamName) {
final Promise<Void> releasePromise = new Promise<Void>();
java.util.concurrent.Future<?> scheduleFuture = schedule(new Runnable() {
@Override
public void run() {
releasePromise.become(doCloseAndRemoveAsync(streamName));
}
}, 0);
if (null == scheduleFuture) {
return Future.exception(new ServiceUnavailableException("Couldn't schedule a release task."));
}
return releasePromise;
}
Aggregations