ZooKeeper
  1. ZooKeeper
  2. ZOOKEEPER-502

bookkeeper create calls completion too many times

    Details

    • Type: Bug Bug
    • Status: Closed
    • Priority: Major Major
    • Resolution: Fixed
    • Affects Version/s: None
    • Fix Version/s: 3.3.0
    • Component/s: contrib-bookkeeper
    • Labels:
      None

      Description

      when calling the asynchronous version of create, the completion routine is called more than once.

        Issue Links

          Activity

          Hide
          Mahadev konar added a comment -

          Committed in ZOOKEEPER-507.

          Show
          Mahadev konar added a comment - Committed in ZOOKEEPER-507 .
          Hide
          Utkarsh Srivastava added a comment -

          The cause is the following:

          In Action 1 of createLedger, 4 calls to zk are fired off : one getChildren() and 3 create()s. The callback for the getChildren() moves the op into Action 2 which is not correct because the 3 creates are still pending. Now the create callback just assumes that its already in action 2, and hence advances to action 3. Now the same op is enqueued twice, and its action has been set to 3. The double queuing explains why the callback is called twice.

          Since in this sequence of events action 2 is skipped altogether, and we end up with 0 bookies. If the dequeuer actually happens to dequeue before the action is set to 3, then action 2 will also be carried out which explains why we get 0 bookies only sometimes and not always (which explains ZOOKEEPER-503).

          In general, this style of asynchronous programming with stage numbers is error-prone, and hard to read. Object creation is cheap, and operations like openLedger and createLedger are rare. Why not just create anonymous inner classes as callbacks instead of doing this state machine?

          Show
          Utkarsh Srivastava added a comment - The cause is the following: In Action 1 of createLedger, 4 calls to zk are fired off : one getChildren() and 3 create()s. The callback for the getChildren() moves the op into Action 2 which is not correct because the 3 creates are still pending. Now the create callback just assumes that its already in action 2, and hence advances to action 3. Now the same op is enqueued twice, and its action has been set to 3. The double queuing explains why the callback is called twice. Since in this sequence of events action 2 is skipped altogether, and we end up with 0 bookies. If the dequeuer actually happens to dequeue before the action is set to 3, then action 2 will also be carried out which explains why we get 0 bookies only sometimes and not always (which explains ZOOKEEPER-503 ). In general, this style of asynchronous programming with stage numbers is error-prone, and hard to read. Object creation is cheap, and operations like openLedger and createLedger are rare. Why not just create anonymous inner classes as callbacks instead of doing this state machine?
          Hide
          Benjamin Reed added a comment -

          this patch adds a test case that reproduces the problem.

          Show
          Benjamin Reed added a comment - this patch adds a test case that reproduces the problem.

            People

            • Assignee:
              Flavio Junqueira
              Reporter:
              Benjamin Reed
            • Votes:
              0 Vote for this issue
              Watchers:
              1 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved:

                Development