CompanyAugust 11, 2015

DataStax C/C++ Driver: 2.1 GA released!

Michael Penick
Michael PenickDataStax
DataStax C/C++ Driver: 2.1 GA released!

We are pleased to announce the 2.1 GA release of the C/C++ driver for Apache Cassandra and DataStax Enterprise. The features of this release and the beta complete all the necessary functionality to take full advantage of Apache Cassandra 2.1 and DataStax Enterprise 4.7. In addition to the features included in the beta release, the 2.1 GA adds support for client-side timestamps and the full range of stream IDs. This release also brings support for retry polices, idle connection heartbeats, the API now exposes the raw paging state token, the ability to disable schema metadata and several internal improvements.

What’s new

Client-side timestamps

Apache Cassandra uses timestamps to serialize write operations. That is, values with a more current timestamp are considered to be the most up-to-date version of that information. Previous versions of the C/C++ driver only allowed timestamps to be assigned server-side by Cassandra. This is not always ideal for all applications. This release of the driver allows timestamps to be generated client-side and it is enabled by either setting a global timestamp generator or assigning a specific timestamp to a statement or batch. By default, the driver uses a server-side timestamp generator and behaves the same as previous versions of the driver. The GA driver also includes a monotonic timestamp generator which assigns microsecond granular timestamps client-side and is useful for applications that plan to make rapid mutations from a single driver instance. In that case, it can prevent writes from a single driver instance from being reordered.

Using the monotonic timestamp generator

CassTimestampGen* timestamp_gen = cass_timestamp_gen_monotonic_new();

 

cass_cluster_set_timestamp_gen(cluster, timestamp_gen);

/* ... */

/* Connect sessions */

/* Timestamp generators must be freed */
cass_timestamp_gen_free(timestamp_gen);

Timestamps can also be assigned to individual CassStatement or CassBatch.

Assigning a client-side timestamp to a statement

CassStatement* statement = cass_statement_new("INSERT INTO * ...", 2);

/* Add a timestamp to a statement */
cass_statement_set_timestamp(statement, 123456789);

/* ... */


Assigning a client-side timestamp to a batch

/* Add a timestamp to a batch */

CassBatch* batch = cass_batch_new(CASS_BATCH_TYPE_LOGGED);

/* Add a timestamp to the batch */
cass_batch_set_timestamp(batch, 123456789);

/* Add statements to the batch*/

/* ... */

Retry policies

The use of retry policies allows C/C++ driver to automatically handle server-side failures when Cassandra is unable to fulfill the consistency requirements of a request. The default retry policy will only retry a request when it will preseve the original consistency level and when it is likely to succeed (there are enough replicas). The default retry policy can be overridden globally by using cass_cluster_set_retry_policy() or it can be set per CassStatement or CassBatch.

Changing the default policy to the downgrading consistency policy

CassRetryPolicy* downgrading_policy = cass_retry_policy_downgrading_consistency_new();

cass_cluster_set_retry_policy(cluster, downgrading_policy);

/* ... */

/* Retry policies must be freed */
cass_retry_policy_free(downgrading_policy);


The driver also provides a fall-through policy that always returns an error and a logging policy which can be used in conjunction with other policies to log their retry decisions.

Chaining the downgrading policy to the logging policy

CassRetryPolicy* downgrading_policy = cass_retry_policy_downgrading_consistency_new();

CassRetryPolicy* logging_policy = cass_retry_policy_logging_new(downgrading_policy)

cass_cluster_set_retry_policy(cluster, logging_policy);

/* ... */

/* Retry policies must be freed */
cass_retry_policy_free(downgrading_policy);
cass_retry_policy_free(logging_policy);

 

Direct access to the paging state token

Previously, the C/C++ driver handled paging transparently by managing the paging state internally. It is now possible to access this paging state token using cass_result_paging_state_token() and add it to a CassStatement using cass_statement_set_paging_state_token(). This allows client applications to store this token for later use. The paging state should not be exposed to or come from untrusted environments.

Idle connection heartbeats

All the DataStax drivers use connection pooling to help reduce query latency by always having connections ready to handle requests. The problem is that in many networking setups intermediate network devices such as routers and switches can disconnect connections that have been idle for too long. To prevent this from happening the driver can now send a lightweight heartbeat request periodically. By default, the driver sends a heartbeat every 30 seconds, but this can be configured or disabled:

/* Change the heartbeat interval to 1 minute *
cass_cluster_set_connection_heartbeat_interval(cluster, 60);

/* Disable heartbeat requests */
cass_cluster_set_connection_heartbeat_interval(cluster, 0);

Ability to disable schema metadataHeartbeats can also be used to detect unresponsive connections. A connection is determined to be unresponsive if it is without a successful heartbeat for the idle timeout period. The idle timeout period is the amount of time a connection is allowed to be without a successful heartbeat before being terminated and scheduled for reconnection. This timeout can be change from its default setting of 60 seconds:

/* Change the idle timeout to 2 minute */
cass_cluster_set_connection_idle_timeout(cluster, 120);

Ability to disable schema metadata
Schema metadata is kept up-to-date by the driver for use by client applications, either directly, or in the 2.1 release it can be used to construct complex data types such as UDTs, tuples and collections. It is also used by the token aware policy to determine the replication strategy of keyspaces. However, some applications might wish to eliminate this overhead. It is now possible to prevent the driver from retrieving and maintaining the schema metadata. This can be used to improve startup performance in applications with short-lived sessions or applications where schema metadata isn't used.

/* Disable schema metdata */
cass_cluster_set_use_schema(cluster, cass_false);

TCP_NODELAY default

The driver now enables TCP_NODELAY by default because, internally, the driver already buffers writes to connections and disabling TCP_NODELAY (enabling Nagle's algorithm) either has no effect or can add unnecessary delay.

Internal improvements

This release also includes the following internal improvements:

  • Timeouts that happen during connection or start up will no longer disconnect an entire connection pool. Instead the driver attempts to reconnect only the connections that experienced the timeouts.
  • Connections can now use the full 32,767 stream IDs allowed by the CQL Native Protocol Version 3 (vs the 127 stream IDs available in version 1 and 2) . This allows for bigger write batches and allows the driver to handle the same throughput with less connections.

Looking forward

This release brings with it full support for Apache Cassandra 2.1 along with many other great features. In next release we will be focusing our efforts on supporting Apache Cassandra 2.2 and 3.0. Let us know what you think about the 2.1 GA release. Your feedback is important to us and it influences what features we prioritize. To provide feedback use the following:

Discover more
DriversC# / .NET
Share

One-stop Data API for Production GenAI

Astra DB gives JavaScript developers a complete data API and out-of-the-box integrations that make it easier to build production RAG apps with high relevancy and low latency.