Repository navigation
RCBC-304: Add Cluster#wait_until_ready and Bucket#wait_until_ready - #277
Merged
Merged
Conversation
avsej
force-pushed
the
rcbc-304-wait-until-ready
branch
from
October 19, 2026 18:09
9655dd0 to
55ea1e1
Compare
avsej
force-pushed
the
rcbc-304-wait-until-ready
branch
from
October 19, 2026 19:02
55ea1e1 to
468e938
Compare
Motivation ---------- cb_backend_to_public_api_cluster() called rb_raise() when the backend was closed. rb_raise() leaves the method body without running its C++ destructors. A binding that had already built an object holding heap memory leaked it. Every binding reaches this function, directly or through cb_backend_to_core_api_cluster(). Modifications ------------- The function throws ruby_exception with Error::ClusterClosed, and the caller's frames unwind before cb_method raises it in Ruby. Backend#cluster_labels, the one caller not yet registered through cb_method, now is. Results ------- Calling a backend method after the cluster is closed raises the same Error::ClusterClosed and message as before, without leaking the caller's objects. The leak itself is not observable from Ruby, so no test covers it.
avsej
force-pushed
the
rcbc-304-wait-until-ready
branch
from
October 19, 2026 19:19
468e938 to
51b5c18
Compare
avsej
force-pushed
the
rcbc-304-wait-until-ready
branch
from
October 19, 2026 19:42
51b5c18 to
4e29aa7
Compare
avsej
force-pushed
the
rcbc-304-wait-until-ready
branch
from
October 19, 2026 19:55
4e29aa7 to
4dc865b
Compare
thejcfactor
reviewed
Oct 19, 2026
thejcfactor
approved these changes
Oct 19, 2026
avsej
force-pushed
the
rcbc-304-wait-until-ready
branch
from
October 20, 2026 16:38
4dc865b to
c2974f8
Compare
avsej
force-pushed
the
rcbc-304-wait-until-ready
branch
from
October 20, 2026 17:19
c2974f8 to
3846f25
Compare
avsej
force-pushed
the
rcbc-304-wait-until-ready
branch
from
October 20, 2026 17:26
3846f25 to
ee2c8e9
Compare
avsej
force-pushed
the
rcbc-304-wait-until-ready
branch
from
October 20, 2026 17:52
ee2c8e9 to
2f13c3e
Compare
Motivation ---------- Cluster.connect and Cluster#bucket return once bootstrap completes. Sessions to the remaining nodes and services may still be opening, and a bucket's replicas may not be placed yet. An operation routed to such a node waits inside its own timeout, and can time out before it is sent. The SDK offers no way to wait for those first. Modifications ------------- Cluster#wait_until_ready(timeout, options) and Bucket#wait_until_ready(timeout, options) wait through the C++ core's wait_until_ready, which pings the services until they respond or the timeout elapses. Options::WaitUntilReady selects the desired state and the service types: - :online waits for every endpoint the ping reports for each requested service. :degraded waits for at least one. - For a bucket, :online also waits until every vbucket has its active copy and each placeable replica assigned to a node. - With no service types, every service in the ping report counts. A requested service that no node runs is never ready. The wait raises Error::UnambiguousTimeout when the timeout elapses, Error::ClusterClosed once the cluster is disconnected, and Error::InvalidArgument for an unknown state or service type, or for a timeout that is negative or too long for the deadline to represent. It works over couchbase:// and couchbases://; couchbase2:// raises Error::FeatureNotAvailable. Results ------- A caller can block until the cluster or bucket serves the services it needs. Thread#raise, Thread#kill and Timeout.timeout do not interrupt the wait. It ends when the state is reached, the timeout elapses, or Cluster#disconnect runs on another thread.
Motivation ---------- Each test that uses CAVES starts its own CAVES cluster. On CI, the first KV operation of such a test sometimes fails with UnambiguousTimeout after the default 2.5 s KV timeout, with retry_attempts 0. Modifications ------------- Under CAVES, TestUtilities#connect calls Bucket#wait_until_ready for the test bucket, with service_types [:kv] and up to 10 s. It returns once every KV endpoint answers a ping and the vbucket map is placed. Runs against a real cluster do not wait. Results ------- A test's first KV operation starts after CAVES answers KV pings. A CAVES cluster not ready within 10 s now fails TestUtilities#connect with Error::UnambiguousTimeout. The rate of the first-operation timeouts on CI before and after this change has not been measured.
avsej
force-pushed
the
rcbc-304-wait-until-ready
branch
from
October 20, 2026 18:45
2f13c3e to
3be3849
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.

Fixes RCBC-304.
Problem
The SDK has no way to wait for a cluster or bucket to become fully usable.
Cluster.connectandCluster#bucketreturn after bootstrap. Sessions to the other nodes and services may still be opening.Change
The first commit makes the backend raise
Error::ClusterClosedas a C++ exception, so a closed cluster no longer skips the calling binding's destructors.The second commit adds
Cluster#wait_until_readyandBucket#wait_until_ready, through the C++ core'swait_until_ready.desired_state: :onlinewaits for every endpoint the ping reports for each requested service.:degradedwaits for at least one.:onlinealso waits until every vbucket has its active copy and each placeable replica assigned to a node.service_types, every service in the ping report counts. A requested service that no node runs is never ready.Error::UnambiguousTimeoutwhen the timeout elapses;Error::ClusterClosedonce the cluster is disconnected;Error::InvalidArgumentfor an unknown state or service type, or for a timeout that is negative or longer than 365 days.The third commit makes the test helper wait for the test bucket under CAVES. On CI, a test's first operation sometimes fails with
UnambiguousTimeoutandretry_attempts: 0.Known gaps
couchbase2://both methods raiseError::FeatureNotAvailable. That client is implemented in Ruby, not over the core.Thread#raiseandTimeout.timeoutdo not interrupt the wait, because the binding blocks without an unblocking function.Cluster#disconnectfrom another thread ends it withError::ClusterClosed.