Search in sources :

Example 1 with Promise

use of com.twitter.util.Promise in project distributedlog by twitter.

the class BKDistributedLogManager method asyncClose.

/**
     * Close the distributed log manager, freeing any resources it may hold.
     */
@Override
public Future<Void> asyncClose() {
    Promise<Void> closeFuture;
    BKLogReadHandler readHandlerToClose;
    synchronized (this) {
        if (null != closePromise) {
            return closePromise;
        }
        closeFuture = closePromise = new Promise<Void>();
        readHandlerToClose = readHandlerForListener;
    }
    // NOTE: the resources {scheduler, writerBKC, readerBKC} are mostly from namespace instance.
    //       so they are not blocking call except tests.
    AsyncCloseable resourcesCloseable = new AsyncCloseable() {

        @Override
        public Future<Void> asyncClose() {
            int schedTimeout = conf.getSchedulerShutdownTimeoutMs();
            // Clean up executor state.
            if (ownExecutor) {
                SchedulerUtils.shutdownScheduler(scheduler, schedTimeout, TimeUnit.MILLISECONDS);
                LOG.info("Stopped BKDL executor service for {}.", name);
                if (scheduler != readAheadScheduler) {
                    SchedulerUtils.shutdownScheduler(readAheadScheduler, schedTimeout, TimeUnit.MILLISECONDS);
                    LOG.info("Stopped BKDL ReadAhead Executor Service for {}.", name);
                }
                SchedulerUtils.shutdownScheduler(getLockStateExecutor(false), schedTimeout, TimeUnit.MILLISECONDS);
                LOG.info("Stopped BKDL Lock State Executor for {}.", name);
            }
            if (ownWriterBKC) {
                writerBKC.close();
            }
            if (ownReaderBKC) {
                readerBKC.close();
            }
            return Future.Void();
        }
    };
    Future<Void> closeResult = Utils.closeSequence(null, true, readHandlerToClose, pendingReaders, resourcesCloseable, new AsyncCloseable() {

        @Override
        public Future<Void> asyncClose() {
            return BKDistributedLogManager.super.asyncClose();
        }
    });
    closeResult.proxyTo(closeFuture);
    return closeFuture;
}
Also used : Promise(com.twitter.util.Promise) AsyncCloseable(com.twitter.distributedlog.io.AsyncCloseable) Future(com.twitter.util.Future)

Example 2 with Promise

use of com.twitter.util.Promise in project distributedlog by twitter.

the class BKLogWriteHandler method deleteLogSegment.

private Future<LogSegmentMetadata> deleteLogSegment(final LogSegmentMetadata ledgerMetadata) {
    LOG.info("Deleting ledger {} for {}", ledgerMetadata, getFullyQualifiedName());
    final Promise<LogSegmentMetadata> promise = new Promise<LogSegmentMetadata>();
    final Stopwatch stopwatch = Stopwatch.createStarted();
    promise.addEventListener(new FutureEventListener<LogSegmentMetadata>() {

        @Override
        public void onSuccess(LogSegmentMetadata segment) {
            deleteOpStats.registerSuccessfulEvent(stopwatch.stop().elapsed(TimeUnit.MICROSECONDS));
        }

        @Override
        public void onFailure(Throwable cause) {
            deleteOpStats.registerFailedEvent(stopwatch.stop().elapsed(TimeUnit.MICROSECONDS));
        }
    });
    try {
        bookKeeperClient.get().asyncDeleteLedger(ledgerMetadata.getLedgerId(), new AsyncCallback.DeleteCallback() {

            @Override
            public void deleteComplete(int rc, Object ctx) {
                if (BKException.Code.NoSuchLedgerExistsException == rc) {
                    LOG.warn("No ledger {} found to delete for {} : {}.", new Object[] { ledgerMetadata.getLedgerId(), getFullyQualifiedName(), ledgerMetadata });
                } else if (BKException.Code.OK != rc) {
                    BKException bke = BKException.create(rc);
                    LOG.error("Couldn't delete ledger {} from bookkeeper for {} : ", new Object[] { ledgerMetadata.getLedgerId(), getFullyQualifiedName(), bke });
                    promise.setException(bke);
                    return;
                }
                // after the ledger is deleted, we delete the metadata znode
                scheduler.submit(new Runnable() {

                    @Override
                    public void run() {
                        deleteLogSegmentMetadata(ledgerMetadata, promise);
                    }
                });
            }
        }, null);
    } catch (IOException e) {
        promise.setException(BKException.create(BKException.Code.BookieHandleNotAvailableException));
    }
    return promise;
}
Also used : AsyncCallback(org.apache.bookkeeper.client.AsyncCallback) Stopwatch(com.google.common.base.Stopwatch) IOException(java.io.IOException) Promise(com.twitter.util.Promise) FutureEventListenerRunnable(com.twitter.distributedlog.util.FutureUtils.FutureEventListenerRunnable) BKException(org.apache.bookkeeper.client.BKException)

Example 3 with Promise

use of com.twitter.util.Promise in project distributedlog by twitter.

the class BookKeeperClient method deleteLedger.

public Future<Void> deleteLedger(long lid, final boolean ignoreNonExistentLedger) {
    BookKeeper bk;
    try {
        bk = get();
    } catch (IOException ioe) {
        return Future.exception(ioe);
    }
    final Promise<Void> promise = new Promise<Void>();
    bk.asyncDeleteLedger(lid, new AsyncCallback.DeleteCallback() {

        @Override
        public void deleteComplete(int rc, Object ctx) {
            if (BKException.Code.OK == rc) {
                promise.updateIfEmpty(new Return<Void>(null));
            } else if (BKException.Code.NoSuchLedgerExistsException == rc) {
                if (ignoreNonExistentLedger) {
                    promise.updateIfEmpty(new Return<Void>(null));
                } else {
                    promise.updateIfEmpty(new Throw<Void>(BKException.create(rc)));
                }
            } else {
                promise.updateIfEmpty(new Throw<Void>(BKException.create(rc)));
            }
        }
    }, null);
    return promise;
}
Also used : Return(com.twitter.util.Return) AsyncCallback(org.apache.bookkeeper.client.AsyncCallback) BookKeeper(org.apache.bookkeeper.client.BookKeeper) IOException(java.io.IOException) Promise(com.twitter.util.Promise)

Example 4 with Promise

use of com.twitter.util.Promise in project distributedlog by twitter.

the class ZKLogMetadataStore method getLogs.

@Override
public Future<Iterator<String>> getLogs() {
    final Promise<Iterator<String>> promise = new Promise<Iterator<String>>();
    final String nsRootPath = namespace.getPath();
    try {
        final ZooKeeper zk = zkc.get();
        zk.sync(nsRootPath, new AsyncCallback.VoidCallback() {

            @Override
            public void processResult(int syncRc, String syncPath, Object ctx) {
                if (KeeperException.Code.OK.intValue() == syncRc) {
                    zk.getChildren(nsRootPath, false, new AsyncCallback.Children2Callback() {

                        @Override
                        public void processResult(int rc, String path, Object ctx, List<String> children, Stat stat) {
                            if (KeeperException.Code.OK.intValue() == rc) {
                                List<String> results = Lists.newArrayListWithExpectedSize(children.size());
                                for (String child : children) {
                                    if (!isReservedStreamName(child)) {
                                        results.add(child);
                                    }
                                }
                                promise.setValue(results.iterator());
                            } else if (KeeperException.Code.NONODE.intValue() == rc) {
                                List<String> streams = Lists.newLinkedList();
                                promise.setValue(streams.iterator());
                            } else {
                                promise.setException(new ZKException("Error reading namespace " + nsRootPath, KeeperException.Code.get(rc)));
                            }
                        }
                    }, null);
                } else if (KeeperException.Code.NONODE.intValue() == syncRc) {
                    List<String> streams = Lists.newLinkedList();
                    promise.setValue(streams.iterator());
                } else {
                    promise.setException(new ZKException("Error reading namespace " + nsRootPath, KeeperException.Code.get(syncRc)));
                }
            }
        }, null);
        zkc.get();
    } catch (ZooKeeperClient.ZooKeeperConnectionException e) {
        promise.setException(e);
    } catch (InterruptedException e) {
        promise.setException(e);
    }
    return promise;
}
Also used : AsyncCallback(org.apache.zookeeper.AsyncCallback) Promise(com.twitter.util.Promise) ZKException(com.twitter.distributedlog.exceptions.ZKException) ZooKeeper(org.apache.zookeeper.ZooKeeper) Stat(org.apache.zookeeper.data.Stat) ZooKeeperClient(com.twitter.distributedlog.ZooKeeperClient) Iterator(java.util.Iterator) List(java.util.List)

Example 5 with Promise

use of com.twitter.util.Promise in project distributedlog by twitter.

the class TestAsyncReaderWriter method testWriteRecordSet.

@Test(timeout = 60000)
public void testWriteRecordSet() throws Exception {
    String name = runtime.getMethodName();
    DistributedLogConfiguration confLocal = new DistributedLogConfiguration();
    confLocal.addConfiguration(testConf);
    confLocal.setOutputBufferSize(0);
    confLocal.setImmediateFlushEnabled(false);
    confLocal.setPeriodicFlushFrequencyMilliSeconds(0);
    URI uri = createDLMURI("/" + name);
    ensureURICreated(uri);
    DistributedLogManager dlm = createNewDLM(confLocal, name);
    BKAsyncLogWriter writer = (BKAsyncLogWriter) dlm.startAsyncLogSegmentNonPartitioned();
    List<Future<DLSN>> writeFutures = Lists.newArrayList();
    for (int i = 0; i < 5; i++) {
        LogRecord record = DLMTestUtil.getLogRecordInstance(1L + i);
        writeFutures.add(writer.write(record));
    }
    List<Future<DLSN>> recordSetFutures = Lists.newArrayList();
    // write another 5 records
    final LogRecordSet.Writer recordSetWriter = LogRecordSet.newWriter(4096, CompressionCodec.Type.LZ4);
    for (int i = 0; i < 5; i++) {
        LogRecord record = DLMTestUtil.getLogRecordInstance(6L + i);
        Promise<DLSN> writePromise = new Promise<DLSN>();
        recordSetWriter.writeRecord(ByteBuffer.wrap(record.getPayload()), writePromise);
        recordSetFutures.add(writePromise);
    }
    final ByteBuffer recordSetBuffer = recordSetWriter.getBuffer();
    byte[] data = new byte[recordSetBuffer.remaining()];
    recordSetBuffer.get(data);
    LogRecord setRecord = new LogRecord(6L, data);
    setRecord.setRecordSet();
    Future<DLSN> writeRecordSetFuture = writer.write(setRecord);
    writeRecordSetFuture.addEventListener(new FutureEventListener<DLSN>() {

        @Override
        public void onSuccess(DLSN dlsn) {
            recordSetWriter.completeTransmit(dlsn.getLogSegmentSequenceNo(), dlsn.getEntryId(), dlsn.getSlotId());
        }

        @Override
        public void onFailure(Throwable cause) {
            recordSetWriter.abortTransmit(cause);
        }
    });
    writeFutures.add(writeRecordSetFuture);
    FutureUtils.result(writeRecordSetFuture);
    // write last 5 records
    for (int i = 0; i < 5; i++) {
        LogRecord record = DLMTestUtil.getLogRecordInstance(11L + i);
        Future<DLSN> writeFuture = writer.write(record);
        writeFutures.add(writeFuture);
        // make sure get log record count returns the right count
        if (i == 0) {
            FutureUtils.result(writeFuture);
            assertEquals(10, dlm.getLogRecordCount());
        }
    }
    List<DLSN> writeResults = FutureUtils.result(Future.collect(writeFutures));
    for (int i = 0; i < 5; i++) {
        Assert.assertEquals(new DLSN(1L, i, 0L), writeResults.get(i));
    }
    Assert.assertEquals(new DLSN(1L, 5L, 0L), writeResults.get(5));
    for (int i = 0; i < 5; i++) {
        Assert.assertEquals(new DLSN(1L, 6L + i, 0L), writeResults.get(6 + i));
    }
    List<DLSN> recordSetWriteResults = Await.result(Future.collect(recordSetFutures));
    for (int i = 0; i < 5; i++) {
        Assert.assertEquals(new DLSN(1L, 5L, i), recordSetWriteResults.get(i));
    }
    FutureUtils.result(writer.flushAndCommit());
    DistributedLogConfiguration readConf1 = new DistributedLogConfiguration();
    readConf1.addConfiguration(confLocal);
    readConf1.setDeserializeRecordSetOnReads(true);
    DistributedLogManager readDLM1 = createNewDLM(readConf1, name);
    AsyncLogReader reader1 = readDLM1.getAsyncLogReader(DLSN.InitialDLSN);
    for (int i = 0; i < 15; i++) {
        LogRecordWithDLSN record = FutureUtils.result(reader1.readNext());
        if (i < 5) {
            assertEquals(new DLSN(1L, i, 0L), record.getDlsn());
            assertEquals(1L + i, record.getTransactionId());
        } else if (i >= 10) {
            assertEquals(new DLSN(1L, 6L + i - 10, 0L), record.getDlsn());
            assertEquals(11L + i - 10, record.getTransactionId());
        } else {
            assertEquals(new DLSN(1L, 5L, i - 5), record.getDlsn());
            assertEquals(6L, record.getTransactionId());
        }
        assertEquals(i + 1, record.getPositionWithinLogSegment());
        assertArrayEquals(DLMTestUtil.generatePayload(i + 1), record.getPayload());
    }
    DistributedLogConfiguration readConf2 = new DistributedLogConfiguration();
    readConf2.addConfiguration(confLocal);
    readConf2.setDeserializeRecordSetOnReads(false);
    DistributedLogManager readDLM2 = createNewDLM(readConf2, name);
    AsyncLogReader reader2 = readDLM2.getAsyncLogReader(DLSN.InitialDLSN);
    for (int i = 0; i < 11; i++) {
        LogRecordWithDLSN record = FutureUtils.result(reader2.readNext());
        LOG.info("Read record {}", record);
        if (i < 5) {
            assertEquals(new DLSN(1L, i, 0L), record.getDlsn());
            assertEquals(1L + i, record.getTransactionId());
            assertEquals(i + 1, record.getPositionWithinLogSegment());
            assertArrayEquals(DLMTestUtil.generatePayload(i + 1), record.getPayload());
        } else if (i >= 6L) {
            assertEquals(new DLSN(1L, 6L + i - 6, 0L), record.getDlsn());
            assertEquals(11L + i - 6, record.getTransactionId());
            assertEquals(11 + i - 6, record.getPositionWithinLogSegment());
            assertArrayEquals(DLMTestUtil.generatePayload(11L + i - 6), record.getPayload());
        } else {
            assertEquals(new DLSN(1L, 5L, 0), record.getDlsn());
            assertEquals(6L, record.getTransactionId());
            assertEquals(6, record.getPositionWithinLogSegment());
            assertTrue(record.isRecordSet());
            assertEquals(5, LogRecordSet.numRecords(record));
        }
    }
}
Also used : URI(java.net.URI) ByteBuffer(java.nio.ByteBuffer) DynamicDistributedLogConfiguration(com.twitter.distributedlog.config.DynamicDistributedLogConfiguration) Promise(com.twitter.util.Promise) Future(com.twitter.util.Future) Test(org.junit.Test)

Aggregations

Promise (com.twitter.util.Promise)48 IOException (java.io.IOException)11 Stat (org.apache.zookeeper.data.Stat)11 Test (org.junit.Test)10 FutureEventListener (com.twitter.util.FutureEventListener)9 ZkVersion (org.apache.bookkeeper.meta.ZkVersion)9 BoxedUnit (scala.runtime.BoxedUnit)9 ZKException (com.twitter.distributedlog.exceptions.ZKException)8 Future (com.twitter.util.Future)8 Versioned (org.apache.bookkeeper.versioning.Versioned)8 Stopwatch (com.google.common.base.Stopwatch)7 UnexpectedException (com.twitter.distributedlog.exceptions.UnexpectedException)7 List (java.util.List)7 AsyncCallback (org.apache.zookeeper.AsyncCallback)7 DLInterruptedException (com.twitter.distributedlog.exceptions.DLInterruptedException)6 Transaction (com.twitter.distributedlog.util.Transaction)6 Version (org.apache.bookkeeper.versioning.Version)6 KeeperException (org.apache.zookeeper.KeeperException)6 ByteBuffer (java.nio.ByteBuffer)5 ArrayList (java.util.ArrayList)5