You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@bookkeeper.apache.org by "Philipp Sushkin (Reopened) (JIRA)" <ji...@apache.org> on 2012/02/07 11:46:59 UTC

[jira] [Reopened] (BOOKKEEPER-162) LedgerHandle.readLastConfirmed does not work

     [ https://issues.apache.org/jira/browse/BOOKKEEPER-162?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

Philipp Sushkin reopened BOOKKEEPER-162:
----------------------------------------


I modified test a little bit to make it fail.

Please find failing version. It changed to use 2 different BookKeeperTestClient to simulate 2 different pc (may failing case) more precisely.

{code}
@Test
    public void testReadFromOpenLedger2() throws Exception {
        try {
            BookKeeperTestClient  writerBkc = new BookKeeperTestClient(baseClientConf);
            BookKeeperTestClient  readerBkc = new BookKeeperTestClient(baseClientConf);
            // Create a ledger
            lh = writerBkc.createLedger(digestType, ledgerPassword);
            // bkc.initMessageDigest("SHA1");
            ledgerId = lh.getId();
            LedgerHandle lhOpen = readerBkc.openLedgerNoRecovery(ledgerId, digestType, ledgerPassword);
            LOG.info("Ledger ID: " + lh.getId());
            for (int i = 0; i < numEntriesToWrite; i++) {
                ByteBuffer entry = ByteBuffer.allocate(4);
                entry.putInt(rng.nextInt(maxInt));
                entry.position(0);

                entries.add(entry.array());
                entriesSize.add(entry.array().length);
                lh.addEntry(entry.array());
                if (i == numEntriesToWrite / 2) {
                    // no recovery opened ledger 's last confirmed entry id is
                    // less than written
                    // and it just can read until (i-1)
                    int toRead = i - 1;
                    long readLastConfirmed = lhOpen.readLastConfirmed();
                    assertTrue(readLastConfirmed != 0);
                    Enumeration<LedgerEntry> readEntry = lhOpen.readEntries(toRead, toRead);
                    assertTrue("Enumeration of ledger entries has no element", readEntry.hasMoreElements() == true);
                    LedgerEntry e = readEntry.nextElement();
                    assertEquals(toRead, e.getEntryId());
                    Assert.assertArrayEquals(entries.get(toRead), e.getEntry());
                    // should not written to a read only ledger
                    try {
                        lhOpen.addEntry(entry.array());
                        fail("Should have thrown an exception here");
                    } catch (BKException.BKIllegalOpException bkioe) {
                        // this is the correct response
                    } catch (Exception ex) {
                        LOG.error("Unexpected exception", ex);
                        fail("Unexpected exception");
                    }

                }
            }
            long last = lh.readLastConfirmed();
            assertTrue("Last confirmed add: " + last, last == (numEntriesToWrite - 2));

            LOG.debug("*** WRITE COMPLETE ***");
            // close ledger
            lh.close();
            // close read only ledger should not change metadata
            lhOpen.close();
        } catch (BKException e) {
            LOG.error("Test failed", e);
            fail("Test failed due to BookKeeper exception");
        } catch (InterruptedException e) {
            LOG.error("Test failed", e);
            fail("Test failed due to interruption");
        }
    }
{code}


I am getting it failing, as I understand, because of "lastEntry > lastAddConfirmed" check.
{code:title=LedgerHandle.java|borderStyle=solid}
    public void asyncReadEntries(long firstEntry, long lastEntry,
                                 ReadCallback cb, Object ctx) {
        // Little sanity check
        if (firstEntry < 0 || lastEntry > lastAddConfirmed
                || firstEntry > lastEntry) {
            cb.readComplete(BKException.Code.ReadException, this, null, ctx);
            return;
        }
...
{code}

So looks like recreation of ledger landle is required every read iteration.

Is it expected?



                
> LedgerHandle.readLastConfirmed does not work
> --------------------------------------------
>
>                 Key: BOOKKEEPER-162
>                 URL: https://issues.apache.org/jira/browse/BOOKKEEPER-162
>             Project: Bookkeeper
>          Issue Type: Bug
>          Components: bookkeeper-client
>    Affects Versions: 4.0.0
>            Reporter: Philipp Sushkin
>            Priority: Critical
>             Fix For: 4.0.0
>
>
> Two bookkeeper clients.
> 1st continuously writing to ledger X.
> 2nd (bk.openLedgerNoRecovery) polling ledger X for new entries and reading them.
> In response we always reveiceing 0 as last confirmed entry id (in fact we are receiving -1 from each bookie RecoveryData but then in ReadLastConfirmedOp, but uninitialized "long maxAddConfirmed;" takes priority in Math.max(...).
> Main question - is given scenario is expected to work at all?

--
This message is automatically generated by JIRA.
If you think it was sent incorrectly, please contact your JIRA administrators: https://issues.apache.org/jira/secure/ContactAdministrators!default.jspa
For more information on JIRA, see: http://www.atlassian.com/software/jira