Search in sources :

Example 1 with GenericCallback

use of org.apache.bookkeeper.proto.BookkeeperInternalCallbacks.GenericCallback in project bookkeeper by apache.

the class LedgerReader method readLacs.

public void readLacs(final LedgerHandle lh, long eid, final GenericCallback<Set<ReadResult<Long>>> callback) {
    WriteSet writeSet = lh.distributionSchedule.getWriteSet(eid);
    final AtomicInteger numBookies = new AtomicInteger(writeSet.size());
    final Set<ReadResult<Long>> readResults = new HashSet<ReadResult<Long>>();
    ReadEntryCallback readEntryCallback = (rc, lid, eid1, buffer, ctx) -> {
        InetSocketAddress bookieAddress = (InetSocketAddress) ctx;
        ReadResult<Long> rr;
        if (BKException.Code.OK != rc) {
            rr = new ReadResult<Long>(eid1, rc, null, bookieAddress);
        } else {
            try {
                DigestManager.RecoveryData data = lh.macManager.verifyDigestAndReturnLastConfirmed(buffer);
                rr = new ReadResult<Long>(eid1, BKException.Code.OK, data.getLastAddConfirmed(), bookieAddress);
            } catch (BKException.BKDigestMatchException e) {
                rr = new ReadResult<Long>(eid1, BKException.Code.DigestMatchException, null, bookieAddress);
            }
        }
        readResults.add(rr);
        if (numBookies.decrementAndGet() == 0) {
            callback.operationComplete(BKException.Code.OK, readResults);
        }
    };
    ArrayList<BookieSocketAddress> ensemble = lh.getLedgerMetadata().getEnsemble(eid);
    for (int i = 0; i < writeSet.size(); i++) {
        int idx = writeSet.get(i);
        bookieClient.readEntry(ensemble.get(idx), lh.getId(), eid, readEntryCallback, ensemble.get(idx), BookieProtocol.FLAG_NONE);
    }
}
Also used : ReadEntryCallback(org.apache.bookkeeper.proto.BookkeeperInternalCallbacks.ReadEntryCallback) FutureEventListener(org.apache.bookkeeper.common.concurrent.FutureEventListener) BookieProtocol(org.apache.bookkeeper.proto.BookieProtocol) GenericCallback(org.apache.bookkeeper.proto.BookkeeperInternalCallbacks.GenericCallback) Set(java.util.Set) BKNoSuchEntryException(org.apache.bookkeeper.client.BKException.BKNoSuchEntryException) InetSocketAddress(java.net.InetSocketAddress) WriteSet(org.apache.bookkeeper.client.DistributionSchedule.WriteSet) Code(org.apache.bookkeeper.client.BKException.Code) Unpooled(io.netty.buffer.Unpooled) ArrayList(java.util.ArrayList) HashSet(java.util.HashSet) List(java.util.List) BookieSocketAddress(org.apache.bookkeeper.net.BookieSocketAddress) ByteBuf(io.netty.buffer.ByteBuf) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) LedgerEntryImpl(org.apache.bookkeeper.client.impl.LedgerEntryImpl) DigestManager(org.apache.bookkeeper.proto.checksum.DigestManager) BookieClient(org.apache.bookkeeper.proto.BookieClient) LedgerEntries(org.apache.bookkeeper.client.api.LedgerEntries) SortedMap(java.util.SortedMap) ReadEntryCallback(org.apache.bookkeeper.proto.BookkeeperInternalCallbacks.ReadEntryCallback) InetSocketAddress(java.net.InetSocketAddress) WriteSet(org.apache.bookkeeper.client.DistributionSchedule.WriteSet) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) BookieSocketAddress(org.apache.bookkeeper.net.BookieSocketAddress) HashSet(java.util.HashSet)

Example 2 with GenericCallback

use of org.apache.bookkeeper.proto.BookkeeperInternalCallbacks.GenericCallback in project bookkeeper by apache.

the class BookieLedgerIndexer method getBookieToLedgerIndex.

/**
 * Generating bookie vs its ledgers map by reading all the ledgers in each
 * bookie and parsing its metadata.
 *
 * @return bookie2ledgersMap map of bookie vs ledgers
 * @throws BKAuditException
 *             exception while getting bookie-ledgers
 */
public Map<String, Set<Long>> getBookieToLedgerIndex() throws BKAuditException {
    // bookie vs ledgers map
    final ConcurrentHashMap<String, Set<Long>> bookie2ledgersMap = new ConcurrentHashMap<String, Set<Long>>();
    final CountDownLatch ledgerCollectorLatch = new CountDownLatch(1);
    Processor<Long> ledgerProcessor = new Processor<Long>() {

        @Override
        public void process(final Long ledgerId, final AsyncCallback.VoidCallback iterCallback) {
            GenericCallback<LedgerMetadata> genericCallback = new GenericCallback<LedgerMetadata>() {

                @Override
                public void operationComplete(int rc, LedgerMetadata ledgerMetadata) {
                    if (rc == BKException.Code.OK) {
                        for (Map.Entry<Long, ArrayList<BookieSocketAddress>> ensemble : ledgerMetadata.getEnsembles().entrySet()) {
                            for (BookieSocketAddress bookie : ensemble.getValue()) {
                                putLedger(bookie2ledgersMap, bookie.toString(), ledgerId);
                            }
                        }
                    } else if (rc == BKException.Code.NoSuchLedgerExistsException) {
                        LOG.info("Ignoring replication of already deleted ledger {}", ledgerId);
                        rc = BKException.Code.OK;
                    } else {
                        LOG.warn("Unable to read the ledger:" + ledgerId + " information");
                    }
                    iterCallback.processResult(rc, null, null);
                }
            };
            ledgerManager.readLedgerMetadata(ledgerId, genericCallback);
        }
    };
    // Reading the result after processing all the ledgers
    final List<Integer> resultCode = new ArrayList<Integer>(1);
    ledgerManager.asyncProcessLedgers(ledgerProcessor, new AsyncCallback.VoidCallback() {

        @Override
        public void processResult(int rc, String s, Object obj) {
            resultCode.add(rc);
            ledgerCollectorLatch.countDown();
        }
    }, null, BKException.Code.OK, BKException.Code.ReadException);
    try {
        ledgerCollectorLatch.await();
    } catch (InterruptedException e) {
        Thread.currentThread().interrupt();
        throw new BKAuditException("Exception while getting the bookie-ledgers", e);
    }
    if (!resultCode.contains(BKException.Code.OK)) {
        throw new BKAuditException("Exception while getting the bookie-ledgers", BKException.create(resultCode.get(0)));
    }
    return bookie2ledgersMap;
}
Also used : Set(java.util.Set) HashSet(java.util.HashSet) Processor(org.apache.bookkeeper.proto.BookkeeperInternalCallbacks.Processor) AsyncCallback(org.apache.zookeeper.AsyncCallback) ArrayList(java.util.ArrayList) BKAuditException(org.apache.bookkeeper.replication.ReplicationException.BKAuditException) BookieSocketAddress(org.apache.bookkeeper.net.BookieSocketAddress) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) GenericCallback(org.apache.bookkeeper.proto.BookkeeperInternalCallbacks.GenericCallback) CountDownLatch(java.util.concurrent.CountDownLatch) LedgerMetadata(org.apache.bookkeeper.client.LedgerMetadata) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) Map(java.util.Map)

Example 3 with GenericCallback

use of org.apache.bookkeeper.proto.BookkeeperInternalCallbacks.GenericCallback in project bookkeeper by apache.

the class TestLongZkLedgerIdGenerator method testGenerateLedgerId.

@Test
public void testGenerateLedgerId() throws Exception {
    // Create *nThread* threads each generate *nLedgers* ledger id,
    // and then check there is no identical ledger id.
    final int nThread = 2;
    final int nLedgers = 2000;
    // Multiply by two. We're going to do half in the old legacy space and half in the new.
    final CountDownLatch countDownLatch = new CountDownLatch(nThread * nLedgers * 2);
    final AtomicInteger errCount = new AtomicInteger(0);
    final ConcurrentLinkedQueue<Long> ledgerIds = new ConcurrentLinkedQueue<Long>();
    final GenericCallback<Long> cb = new GenericCallback<Long>() {

        @Override
        public void operationComplete(int rc, Long result) {
            if (Code.OK.intValue() == rc) {
                ledgerIds.add(result);
            } else {
                errCount.incrementAndGet();
            }
            countDownLatch.countDown();
        }
    };
    long start = System.currentTimeMillis();
    for (int i = 0; i < nThread; i++) {
        new Thread() {

            @Override
            public void run() {
                for (int j = 0; j < nLedgers; j++) {
                    ledgerIdGenerator.generateLedgerId(cb);
                }
            }
        }.start();
    }
    // Go and create the long-id directory in zookeeper. This should cause the id generator to generate ids with the
    // new algo once we clear it's stored status.
    ZkUtils.createFullPathOptimistic(zk, "/test-zk-ledger-id-generator/idgen-long", new byte[0], Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
    ledgerIdGenerator.invalidateLedgerIdGenPathStatus();
    for (int i = 0; i < nThread; i++) {
        new Thread() {

            @Override
            public void run() {
                for (int j = 0; j < nLedgers; j++) {
                    ledgerIdGenerator.generateLedgerId(cb);
                }
            }
        }.start();
    }
    assertTrue("Wait ledger id generation threads to stop timeout : ", countDownLatch.await(120, TimeUnit.SECONDS));
    LOG.info("Number of generated ledger id: {}, time used: {}", ledgerIds.size(), System.currentTimeMillis() - start);
    assertEquals("Error occur during ledger id generation : ", 0, errCount.get());
    Set<Long> ledgers = new HashSet<Long>();
    while (!ledgerIds.isEmpty()) {
        Long ledger = ledgerIds.poll();
        assertNotNull("Generated ledger id is null : ", ledger);
        assertFalse("Ledger id [" + ledger + "] conflict : ", ledgers.contains(ledger));
        ledgers.add(ledger);
    }
}
Also used : CountDownLatch(java.util.concurrent.CountDownLatch) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) ConcurrentLinkedQueue(java.util.concurrent.ConcurrentLinkedQueue) GenericCallback(org.apache.bookkeeper.proto.BookkeeperInternalCallbacks.GenericCallback) HashSet(java.util.HashSet) Test(org.junit.Test)

Example 4 with GenericCallback

use of org.apache.bookkeeper.proto.BookkeeperInternalCallbacks.GenericCallback in project bookkeeper by apache.

the class TestPerChannelBookieClient method testDisconnectRace.

/**
 * Test that all resources are freed if connections and disconnections
 * are interleaved randomly.
 *
 * {@link https://issues.apache.org/jira/browse/BOOKKEEPER-620}
 */
@Test
public void testDisconnectRace() throws Exception {
    final GenericCallback<PerChannelBookieClient> nullop = new GenericCallback<PerChannelBookieClient>() {

        @Override
        public void operationComplete(int rc, PerChannelBookieClient client) {
        // do nothing, we don't care about doing anything with the connection,
        // we just want to trigger it connecting.
        }
    };
    final int iterations = 100000;
    EventLoopGroup eventLoopGroup = new NioEventLoopGroup();
    OrderedExecutor executor = getOrderedSafeExecutor();
    BookieSocketAddress addr = getBookie(0);
    final PerChannelBookieClient client = new PerChannelBookieClient(executor, eventLoopGroup, addr, authProvider, extRegistry);
    final AtomicBoolean shouldFail = new AtomicBoolean(false);
    final AtomicBoolean running = new AtomicBoolean(true);
    final CountDownLatch disconnectRunning = new CountDownLatch(1);
    Thread connectThread = new Thread() {

        public void run() {
            try {
                if (!disconnectRunning.await(10, TimeUnit.SECONDS)) {
                    LOG.error("Disconnect thread never started");
                    shouldFail.set(true);
                }
            } catch (InterruptedException ie) {
                LOG.error("Connect thread interrupted", ie);
                Thread.currentThread().interrupt();
                running.set(false);
            }
            for (int i = 0; i < iterations && running.get(); i++) {
                client.connectIfNeededAndDoOp(nullop);
            }
            running.set(false);
        }
    };
    Thread disconnectThread = new Thread() {

        public void run() {
            disconnectRunning.countDown();
            while (running.get()) {
                client.disconnect();
            }
        }
    };
    Thread checkThread = new Thread() {

        public void run() {
            ConnectionState state;
            Channel channel;
            while (running.get()) {
                synchronized (client) {
                    state = client.state;
                    channel = client.channel;
                    if ((state == ConnectionState.CONNECTED && (channel == null || !channel.isActive())) || (state != ConnectionState.CONNECTED && channel != null && channel.isActive())) {
                        LOG.error("State({}) and channel({}) inconsistent " + channel, state, channel == null ? null : channel.isActive());
                        shouldFail.set(true);
                        running.set(false);
                    }
                }
            }
        }
    };
    connectThread.start();
    disconnectThread.start();
    checkThread.start();
    connectThread.join();
    disconnectThread.join();
    checkThread.join();
    assertFalse("Failure in threads, check logs", shouldFail.get());
    client.close();
    eventLoopGroup.shutdownGracefully();
    executor.shutdown();
}
Also used : Channel(io.netty.channel.Channel) OrderedExecutor(org.apache.bookkeeper.common.util.OrderedExecutor) CountDownLatch(java.util.concurrent.CountDownLatch) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) EventLoopGroup(io.netty.channel.EventLoopGroup) NioEventLoopGroup(io.netty.channel.nio.NioEventLoopGroup) BookieSocketAddress(org.apache.bookkeeper.net.BookieSocketAddress) ConnectionState(org.apache.bookkeeper.proto.PerChannelBookieClient.ConnectionState) GenericCallback(org.apache.bookkeeper.proto.BookkeeperInternalCallbacks.GenericCallback) NioEventLoopGroup(io.netty.channel.nio.NioEventLoopGroup) Test(org.junit.Test)

Example 5 with GenericCallback

use of org.apache.bookkeeper.proto.BookkeeperInternalCallbacks.GenericCallback in project bookkeeper by apache.

the class TestPerChannelBookieClient method testConnectRace.

/**
 * Test race scenario found in {@link https://issues.apache.org/jira/browse/BOOKKEEPER-5}
 * where multiple clients try to connect a channel simultaneously. If not synchronised
 * correctly, this causes the netty channel to get orphaned.
 */
@Test
public void testConnectRace() throws Exception {
    GenericCallback<PerChannelBookieClient> nullop = new GenericCallback<PerChannelBookieClient>() {

        @Override
        public void operationComplete(int rc, PerChannelBookieClient pcbc) {
        // do nothing, we don't care about doing anything with the connection,
        // we just want to trigger it connecting.
        }
    };
    EventLoopGroup eventLoopGroup = new NioEventLoopGroup();
    OrderedExecutor executor = getOrderedSafeExecutor();
    BookieSocketAddress addr = getBookie(0);
    for (int i = 0; i < 100; i++) {
        PerChannelBookieClient client = new PerChannelBookieClient(executor, eventLoopGroup, addr, authProvider, extRegistry);
        for (int j = i; j < 10; j++) {
            client.connectIfNeededAndDoOp(nullop);
        }
        client.close();
    }
    eventLoopGroup.shutdownGracefully();
    executor.shutdown();
}
Also used : EventLoopGroup(io.netty.channel.EventLoopGroup) NioEventLoopGroup(io.netty.channel.nio.NioEventLoopGroup) BookieSocketAddress(org.apache.bookkeeper.net.BookieSocketAddress) OrderedExecutor(org.apache.bookkeeper.common.util.OrderedExecutor) GenericCallback(org.apache.bookkeeper.proto.BookkeeperInternalCallbacks.GenericCallback) NioEventLoopGroup(io.netty.channel.nio.NioEventLoopGroup) Test(org.junit.Test)

Aggregations

GenericCallback (org.apache.bookkeeper.proto.BookkeeperInternalCallbacks.GenericCallback)13 Test (org.junit.Test)6 HashSet (java.util.HashSet)5 CountDownLatch (java.util.concurrent.CountDownLatch)5 AtomicInteger (java.util.concurrent.atomic.AtomicInteger)5 BookieSocketAddress (org.apache.bookkeeper.net.BookieSocketAddress)4 ArrayList (java.util.ArrayList)3 Set (java.util.Set)3 Checkpoint (org.apache.bookkeeper.bookie.CheckpointSource.Checkpoint)3 Channel (io.netty.channel.Channel)2 EventLoopGroup (io.netty.channel.EventLoopGroup)2 NioEventLoopGroup (io.netty.channel.nio.NioEventLoopGroup)2 List (java.util.List)2 Map (java.util.Map)2 ConcurrentLinkedQueue (java.util.concurrent.ConcurrentLinkedQueue)2 GarbageCollector (org.apache.bookkeeper.bookie.GarbageCollector)2 ScanAndCompareGarbageCollector (org.apache.bookkeeper.bookie.ScanAndCompareGarbageCollector)2 LedgerMetadata (org.apache.bookkeeper.client.LedgerMetadata)2 OrderedExecutor (org.apache.bookkeeper.common.util.OrderedExecutor)2 AsyncCallback (org.apache.zookeeper.AsyncCallback)2