The Couchbase Java SDK 2.1.0 arrived!

On behalf of the whole team I'm happy to report that we've finally released the 2.1.0 version of the Couchbase Java SDK. Compared to the 2.0 branch it brings lots of new features as well as a myriad of smaller enhancements and bug fixes. It is the result of the incredible valuable feedback that we received from more and more users that are upgrading their applications as well as new users exploring reactive data access patterns.

In this blog post we'll be focussing on the new features. If you want to check out the full list of changes, please refer to the Release Notes. If you have questions you can ask them on the Forums and if you think you've hit an issue, please file it on our JIRA.

Oh and by the way, we've also pushed some changes that should improve the performance under certain workloads. Even if there are no benchmarks in this blog post, there is a good chance that you'll see improved latency and throughput compared to 2.0.3.

Getting the SDK

N1QL DP4 Support

This release brings official (yet still experimental) support for N1QL DP4. It is not backwards compatible with DP3 because the underlying streaming responses have changed quite a bit. Highlights include:

Simple, parametrized and prepared Statements.

Extended query options like timeouts and scan consistency.

Enhanced synchronous and asynchronous QueryResults for more flexible error handling.

Simon wrote a great blog post two weeks ago, so if you want to learn more you should check it out here.

Spatial View Query Support

In addition to regular View query support, we've added support for spatial View queries. Note that spatial query support is still experimental in Couchbase Server 3.0.2, but will soon be officially supported. Also, the implementation in 2.1.0 is not compatible with older Couchbase Server releases because the response format has slightly changed.

As a quick example, imagine you are storing shop information:

Based on this data format you can define a spatial view which will not only index the latitude and longitude, but also its opening hours:

You can then query it in all three dimensions, by providing a bounding box for the location and also a time range when the shop should be open:

You can expect to see more blog posts and examples coming in the near future as we approach a fully supported version on the server side.

Idle Socket Heartbeats/Keepalive

When there is no load going through the client to a specific socket, there is a chance that a firewall (or something else) is cutting off the connection because it thinks it is stale. In order to prevent this, the SDK now sends a heartbeat message every 30 seconds over idle sockets. These messages are of course not sent if regular traffic is flowing in this interval.

You can change the interval on the environment and if you want to disable it just set it to 0.

Pluggable Retry Strategies

A heavily requested feature was to provide ways to fail fast if the request cannot be dispatched immediately. For example the time between a node fails and it is failed over in the cluster a subset of the documents cannot be written (all that target the specific partitions on this node). By default, the SDK will retry the operation a bit later and eventually it will time out on the caller side.

The new fail fast mode instead would immediately cancel the request, providing faster feedback loops to the caller who then can determine if the request should be retried or not. This new strategy can be enabled on the environment like this:

In addition, we made the retry strategy pluggable so you can even define your own. Since this is quite advanced it is not covered in this blog post, but you can expect more information soon in the documentation on that topic. In the meantime if you are curious, just check out the (quite simple) strategies that ship with the SDK.

Finally, a configurable “maximum request lifetime” has been added to the environment which is utilized by the default “best effort” strategy to determine if the request should still be retried or is cancelled instead. This is needed in order to avoid requests circling around for a very long time and take up precious slots in the RingBuffers.

Subscribable Event Bus

A generic event bus has been added to the environment which is utilized by the core and the client to publish events to potential application subscribers. Currently, only Bucket open/close and Node connect/disconnect events are published, but in the future we plan to greatly extend this by also collecting and publishing performance metrics and other types of events and warnings.

It is very easy to subscribe and react to those kind of events, thanks to RxJava and the streaming nature of our Observables:

DNS SRV Bootstrap

It is now possible to fetch the list of bootstrap nodes through a DNS SRV record. This allows system administrators to centralize their bootstrap node list config in a very easy manner. It needs to be enabled on the environment to make it work. You can find more information here.

What's next?

While we already have many ideas for a 2.2 release, we are now taking a step back and are planning to further stabilize this branch with bugfix releases as needed. In addition, we are shifting the focus to enhanced framework and “up the stack” integration – so stay tuned in the next couple of weeks for blog posts and announcements!

Posted by Michael Nitschinger

Michael Nitschinger works as a Principal Software Engineer at Couchbase. He is the architect and maintainer of the Couchbase Java SDK, one of the first completely reactive database drivers on the JVM. He also authored and maintains the Couchbase Spark Connector. Michael is active in the open source community, a contributor to various other projects like RxJava and Netty.