Repository navigation
API Reference: https://docs.couchbase.com/sdk-api/couchbase-ruby-client-3.9.0/index.html
Full Changelog: 3.8.2...3.9.0
Rubygems: https://rubygems.org/gems/couchbase/versions/3.9.0
gem "couchbase", "3.9.0"gem "couchbase", "3.9.0", :source => "https://packages.couchbase.com/clients/ruby"The C++ core moves from 1.3.3 to 1.5.0. Changes that the core brings are listed with their CXXCBC ticket.
Behaviour changes. These need review before upgrading from 3.8.x:
- TLS connections now verify the server certificate against the dialed hostname (CXXCBC-838). A certificate that does not match the hostname now fails the handshake.
- Query, analytics, search, eventing and management requests raise
Error::InvalidArgumentfor an unrecognised HTTP 400 (CXXCBC-1049). SDK-RFC 0058 requires it. retry_strategy:takes:best_effortor:fail_fast(RCBC-582). On the operations that honour it, any other value, such as aProc, raisesError::InvalidArgument.- An
Options::Basesubclass defined by the application must yield in its owninitialize(RCBC-583).Options::Baseno longer yields for subclasses. Bucket#pingreports the cluster-level HTTP services as well as key-value (CXXCBC-845, CXXCBC-1022).- The application telemetry latency histograms for HTTP services report
_sumin milliseconds (CXXCBC-1002). Dashboards built on the old values need review.
New Features
-
RCBC-558, CXXCBC-980: Read a Named Replica --
Collection#get_replicareads one specific replica of a document, as defined by SDK-RFC 0053.get_any_replicareturns whichever copy answers first.get_replicalets the application choose the copy.- The copy is selected with
GetReplicaStrategy.from_index(:first), or:secondand:third. The active copy cannot be selected. - The result is a
GetReplicaResult, andreplica?istrue. - Three new errors describe why the chosen copy cannot answer. The first two are raised without a network round trip.
Error::ReplicaIndexOutOfBounds: the bucket has fewer replicas than the index.Error::ReplicaIndexCurrentlyUnavailable: the replica is configured but not placed on a node.Error::DocumentNotFoundOnReplica: the replica does not hold the document. It subclassesError::DocumentNotFound.
GetReplicaStrategy.from_index(:first, wrap: true)reads the next readable replica instead of failing. It still fails if the bucket has no replicas, or if no replica is readable.- The replica is chosen from the vBucket map, not from node health. A read of a replica whose node is down waits until its timeout. The API reference shows how to bound the wait and fall back to
get_any_replica. - Over
couchbase2://the operation raisesError::FeatureNotAvailable.
-
RCBC-304, CXXCBC-845: wait_until_ready --
Cluster#wait_until_readyandBucket#wait_until_readyping the services until they respond or the timeout elapses.Options::WaitUntilReadyselects the desired state and the service types.:onlinewaits for every endpoint of each requested service.:degradedwaits for at least one.- For a bucket,
:onlinealso waits for the vBucket map. Every vBucket needs its active copy and each placeable replica on a node. - The wait raises
Error::UnambiguousTimeouton timeout, andError::ClusterClosedonceCluster#disconnecthas run. Thread#raise,Thread#killandTimeout.timeoutdo not interrupt the wait.- Over
couchbase2://the wait raisesError::FeatureNotAvailable.
-
RCBC-554, CXXCBC-911: Hybrid Search Score Fusion --
Options::Search#scoringcontrols how a hybrid search merges its FTS and vector results into one ranked list.SearchScoring.reciprocal_rank_fusionmerges the two lists by rank. It acceptsrank_constantandwindow_size.SearchScoring.relative_score_fusionmerges the two lists by normalized score. It acceptswindow_size.SearchScoring.noneturns scoring off.- Both fusion strategies require Couchbase Server 8.1. On an older server the request raises
Error::FeatureNotAvailable. - Over
couchbase2://onlySearchScoring.noneis supported. The fusion strategies raiseError::FeatureNotAvailable. - The two fusion strategies are uncommitted.
- Setting both
scoringanddisable_scoringraisesError::InvalidArgument.
-
RCBC-582: Retry Strategy per Operation -- Key-value operations honour
retry_strategy:.:fail_fastmakes a request fail at once instead of retrying. A mutation on a locked document then raisesError::DocumentLockedimmediately.:best_effortandnilkeep the default strategy of theClusterobject.- These operations honour the option:
get_multi,upsert_multiandremove_multi;get_replica;- every other single-document operation except the replica reads below.
- These operations ignore the option:
get_any_replica,get_all_replicas,lookup_in_any_replicaandlookup_in_all_replicas.- Range scans.
- Query, analytics, search and view requests.
- Observe requests issued for
persist_to:andreplicate_to:still use the default strategy.
-
CXXCBC-978: Log Redaction -- With
log_redaction=truein the connection string, the core tags sensitive values in its log messages.<ud>marks user data,<md>metadata and<sd>system data.- A tool such as
cblogredactionthen strips or hashes them before the logs are shared. - The setting is off by default. When it is off, log output is unchanged.
-
RCBC-575: ActiveSupport Cache Mutation Tracking -- The
mutation_tracking:store option selects which writesdelete_matchedandclearwait for.:last, the default, waits for the last write, as before.:allwaits for the newest write to every vBucket the store wrote to.- Any object that responds to
recordandmutation_statecan be given instead. - Writes by other store instances or processes are not covered.
Improvements
-
Vector Search Committed --
VectorSearch,VectorQueryandSearchRequest#vector_searchare no longer marked uncommitted. -
Platforms -- Precompiled gems are published for more platforms:
- Windows x64 (
x64-mingw-ucrt). - Windows arm64 (
aarch64-mingw-ucrt). This gem does not depend ongrpc, socouchbase2://is unavailable on it. - Linux arm64 with musl (
aarch64-linux-musl). - The musl gems are built on Alpine 3.21.
- Windows x64 (
-
RCBC-480: Windows Connections -- The extension links Winsock ahead of the Ruby library on MinGW. Every connection previously failed with
WSAENOTSOCK.
Security Fixes
-
CXXCBC-1072, CXXCBC-1106: Management Request Encoding -- Names and values passed by the application can no longer change the meaning of a management request.
- User and group upsert bodies are now form-encoded. A password such as
Pw123456&roles=adminpreviously added arolesfield. - Names placed into REST paths are now escaped. A
#,?or/in a name could cut the path short or address a different entity.
- User and group upsert bodies are now form-encoded. A password such as
-
CXXCBC-981: vBucket Map Bounds Check -- Replica reads no longer index past the end of a vBucket map row. A row is short right after replicas are added to a bucket. Such a read could route a request to a node that does not hold the vBucket.
-
CXXCBC-837: MCBP Frame Bounds Check -- A key-value response frame whose prefix length exceeds its body length is rejected. It previously drove the parser past the receive buffer.
-
CXXCBC-836: Analytics Identifier Quoting -- Bucket, scope and collection names are quoted and escaped in the Analytics statements the SDK composes.
Bug Fixes
-
RCBC-559, RCBC-567, RCBC-586, RCBC-304: Memory Leaks on Errors and Interrupts -- A failing operation no longer leaks its request, its response or its reference to the core cluster.
- 100,000 gets of a missing document grew RSS by about 23 MB.
Timeout.timeout,Thread#killor a signal during an operation leaked its response. RSS growth per interrupted 4 MiB get drops from about 4 MiB to under 0.2 MiB.- These leaked the arguments already copied:
- a tracer that raises;
- an
inspectthat raises; - an out-of-range Integer;
- a non-Symbol durability option.
- A dynamic Symbol as a view namespace no longer crashes the process. It raises
ArgumentError. - Errors reach Ruby with the same class, message and backtrace as before.
- An interrupt that arrives just before an operation now takes effect when the operation completes. That can be as late as the operation timeout.
-
RCBC-568: Logger Hang -- A failing Ruby logger callback no longer hangs the process.
- The failure can be a non-
StandardErrorexception, aTimeoutor aThread#kill. - The sink mutex stayed locked, and the next flush blocked while holding the GVL. The process then ignored
SIGTERM. - Unwritten messages, including the one whose callback failed, are delivered by the next flush.
Couchbase.set_logger(nil)no longer raisesArgumentError.
- The failure can be a non-
-
RCBC-571, CXXCBC-913, CXXCBC-914, CXXCBC-1087: fork() Handling -- The child is now notified as the child.
- The child was notified as the parent, so it restarted the I/O it inherited. Both processes read the same sockets.
- An asynchronous exception during the fork no longer leaves the parent's
Clusterobjects stopped. - The child closes the sockets it inherited before it starts its own I/O.
- The child reopens each
Clusterobject without waiting for its bootstrap (CXXCBC-1087). Requests issued meanwhile are held until the bootstrap completes. Each request is still bounded by its own timeout.
-
RCBC-564: Range Scan Use-After-Free -- A scan result keeps the core cluster behind its
Clusterobject alive. Freeing the result afterCluster#disconnectcould crash or hang the process. So could freeing both in one GC sweep. -
RCBC-566: replica? Flag --
GetReplicaResult#replica?now reports whetherget_any_replicaandget_all_replicasreturned a replica. It previously returnednilovercouchbase://. -
RCBC-580: Raw Query and Analytics Parameters -- Raw parameters reach the server as given.
- A Symbol key passed to
Options::Query#rawsilently dropped that parameter and every raw parameter after it. Options::Analytics#rawsent the entry as a statement binding$name. It is now sent as a request option.- A non-String key or value now raises
ArgumentError. Such entries were previously dropped. This covers:- query and analytics parameters, raw and named;
- search raw parameters.
- A Symbol key passed to
-
RCBC-584: Raw View Parameters --
Options::View#rawraisedNoMethodErroron every call, and stored values were never sent. Raw view parameters are now form-encoded and sent. -
RCBC-583: Options Block -- A block passed to an options constructor runs once, after the defaults are set.
Options::Query.new { |o| o.raw("k", 1) }previously raisedNoMethodError. -
RCBC-574: ActiveSupport Cache After Multi-Key Writes --
delete_matchedandclearno longer raiseNoMethodErrorafterwrite_multiordelete_multi. -
RCBC-569: Histogram Lock -- A non-Float percentile no longer leaves
HdrHistogramClocked. The nextrecord_valuepreviously aborted or blocked every Ruby thread. Integer percentiles are now accepted. -
RCBC-573: Log Timestamps on macOS -- Log times carry the correct sub-second part. On macOS it was a thousand times too small.
-
Windows Exit Hang -- A process that loads the extension no longer hangs at exit on Windows.
-
libstdc++ Symbol Interposition -- Precompiled Linux gems no longer export the libstdc++ symbols they link statically. They interposed on the system libstdc++ and crashed other C++ extensions, such as
mini_racer. -
CXXCBC-984, CXXCBC-985, CXXCBC-986, CXXCBC-987, CXXCBC-1022, CXXCBC-1023, CXXCBC-1090, CXXCBC-1093: Request Completion -- Several core paths no longer drop a key-value request without completing it.
- A request waiting in a retry backoff when the
Clusterobject closes now completes with an error. - A key-value request's timeout now includes the wait for its bucket to open.
- A range scan of a missing collection fails at once with
Error::CollectionNotFound. pingno longer completes before every ping request has been sent.
- A request waiting in a retry backoff when the
-
CXXCBC-1039, CXXCBC-1046, CXXCBC-1048: HTTP Session Lifecycle -- HTTP session shutdown is serialised and runs once. Closing a busy session no longer causes a use-after-free.
-
CXXCBC-1057: Client Certificate Rotation -- A certificate set with
Cluster#update_authenticatoris used by the next HTTP request. Pooled HTTP connections previously kept the old certificate until their idle timeout. -
CXXCBC-882, CXXCBC-1059: Query Error Mapping --
- Query error 2120 (
E_ADMIN_AUTH) raisesError::AuthenticationFailure. - Dropping a query index that does not exist raises
Error::IndexNotFound, whatever HTTP status the server returns.
- Query error 2120 (
-
CXXCBC-823, CXXCBC-839, CXXCBC-841, CXXCBC-876: Connection Management -- Fixes from core 1.4.0:
- A cluster-level configuration no longer displaces a bucket's configuration. This caused stale routing and Not-My-VBucket loops during failover and rebalance.
- Dead idle pooled HTTP connections are detected and closed.
- Bucket create and update work against Couchbase Server 8.1.
-
CXXCBC-785, CXXCBC-787, CXXCBC-788, CXXCBC-797: Key-Value Correctness -- A projected
getwith more than 16 paths no longer fails when a path is missing.lookup_in_all_replicasreports its paths and total failure correctly.
Deprecations
- RCBC-554: Options::Search#disable_scoring -- Replaced by
scoring: SearchScoring.none, which sends the same request.
Build and Test Infrastructure
- The test suite runs on Windows x64 and arm64 against CAVES.
rake compileuses the dependencies and CA bundle vendored inext/cache.- The gem no longer ships a copy of the core's BoringSSL patch for MinGW.