| 646 | |
| 647 | |
| 648 | Result<bool> GroupProcess::doCancel(const Group::Membership& membership) |
| 649 | { |
| 650 | CHECK_EQ(state, READY); |
| 651 | |
| 652 | string path = path::join( |
| 653 | znode, |
| 654 | zkBasename(membership), |
| 655 | os::POSIX_PATH_SEPARATOR); |
| 656 | |
| 657 | LOG(INFO) << "Trying to remove '" << path << "' in ZooKeeper"; |
| 658 | |
| 659 | // Remove ephemeral node. |
| 660 | int code = zk->remove(path, -1); |
| 661 | |
| 662 | if (code == ZINVALIDSTATE || (code != ZOK && zk->retryable(code))) { |
| 663 | CHECK_NE(zk->getState(), ZOO_AUTH_FAILED_STATE); |
| 664 | return None(); |
| 665 | } else if (code == ZNONODE) { |
| 666 | // This can happen because the membership could have expired but |
| 667 | // we have yet to receive the update about it. |
| 668 | return false; |
| 669 | } else if (code != ZOK) { |
| 670 | return Error( |
| 671 | "Failed to remove ephemeral node '" + path + |
| 672 | "' in ZooKeeper: " + zk->message(code)); |
| 673 | } |
| 674 | |
| 675 | // Invalidate the cache (it will/should get immediately populated |
| 676 | // via the 'updated' callback of our ZooKeeper watcher). |
| 677 | memberships = None(); |
| 678 | |
| 679 | // Let anyone waiting know the membership has been cancelled. |
| 680 | CHECK(owned.count(membership.id()) == 1); |
| 681 | Promise<bool>* cancelled = owned[membership.id()]; |
| 682 | cancelled->set(true); |
| 683 | owned.erase(membership.id()); |
| 684 | delete cancelled; |
| 685 | |
| 686 | return true; |
| 687 | } |
| 688 | |
| 689 | |
| 690 | Result<Option<string>> GroupProcess::doData( |