| 480 | |
| 481 | |
| 482 | Result<bool> ZooKeeperStorageProcess::doSet(const Entry& entry, |
| 483 | const id::UUID& uuid) |
| 484 | { |
| 485 | CHECK_NONE(error) << ": " << error.get(); |
| 486 | CHECK(state == CONNECTED); |
| 487 | |
| 488 | // Serialize to make sure we're under the 1 MB limit. |
| 489 | string data; |
| 490 | |
| 491 | if (!entry.SerializeToString(&data)) { |
| 492 | return Error("Failed to serialize Entry"); |
| 493 | } |
| 494 | |
| 495 | if (data.size() > 1024 * 1024) { // 1 MB |
| 496 | // TODO(benh): Use stout/gzip.hpp for compression. |
| 497 | return Error("Serialized data is too big (> 1 MB)"); |
| 498 | } |
| 499 | |
| 500 | string result; |
| 501 | Stat stat; |
| 502 | |
| 503 | int code = zk->get(znode + "/" + entry.name(), false, &result, &stat); |
| 504 | |
| 505 | if (code == ZNONODE) { |
| 506 | // Create directory path znodes as necessary. |
| 507 | CHECK(znode.size() == 0 || znode.at(znode.size() - 1) != '/'); |
| 508 | size_t index = znode.find('/', 0); |
| 509 | |
| 510 | while (index < string::npos) { |
| 511 | // Get out the prefix to create. |
| 512 | index = znode.find('/', index + 1); |
| 513 | string prefix = znode.substr(0, index); |
| 514 | |
| 515 | // Create the znode (even if it already exists). |
| 516 | code = zk->create(prefix, "", acl, 0, nullptr); |
| 517 | |
| 518 | if (code == ZINVALIDSTATE || (code != ZOK && zk->retryable(code))) { |
| 519 | CHECK(zk->getState() != ZOO_AUTH_FAILED_STATE); |
| 520 | return None(); // Try again later. |
| 521 | } else if (code != ZOK && code != ZNODEEXISTS) { |
| 522 | return Error( |
| 523 | "Failed to create '" + prefix + |
| 524 | "' in ZooKeeper: " + zk->message(code)); |
| 525 | } |
| 526 | } |
| 527 | |
| 528 | code = zk->create(znode + "/" + entry.name(), data, acl, 0, nullptr); |
| 529 | |
| 530 | if (code == ZNODEEXISTS) { |
| 531 | return false; // Lost a race with someone else. |
| 532 | } else if (code == ZINVALIDSTATE || (code != ZOK && zk->retryable(code))) { |
| 533 | CHECK(zk->getState() != ZOO_AUTH_FAILED_STATE); |
| 534 | return None(); // Try again later. |
| 535 | } else if (code != ZOK) { |
| 536 | return Error( |
| 537 | "Failed to create '" + znode + "/" + entry.name() + |
| 538 | "' in ZooKeeper: " + zk->message(code)); |
| 539 | } |