Cluster and schema metadata

You can retrieve the cluster topology and the schema metadata information using the Node.js driver.

After establishing the first connection, the driver retrieves the cluster topology details and exposes these through properties of the client object. This information is kept up to date using Cassandra event notifications.

The following example outputs hosts information about your cluster:

client.hosts.forEach(function (host) {
   console.log(host.address, host.datacenter, host.rack);
});

Additionally, the keyspaces information is already loaded into the Metadata object, once the client is connected:

console.log(Object.keys(client.metadata.keyspaces));

To retrieve the definition of a table, use the Metadata#getTable() method:

client.metadata.getTable('ks1', 'table1')
  .then(function (tableInfo) {
    console.log('Table %s', table.name);
    table.columns.forEach(function (column) {
       console.log('Column %s with type %j', column.name, column.type);
    });
  });

When retrieving the same table definition concurrently, the driver queries once and invokes all callbacks with the retrieved information.

Schema agreement

Schema changes need to be propagated to all nodes in the cluster. Once they have settled on a common version, we say that they are in agreement.

the driver waits for schema agreement after executing a schema-altering query. This is to ensure that subsequent requests (which might get routed to different nodes) see an up-to-date version of the schema.

Text Diagram

The schema agreement wait is performed serially, so the execute() call will only return after it has completed.

The check is implemented by repeatedly querying system tables for the schema version reported by each node, until they all converge to the same value. If that doesn’t happen within a given timeout, the driver will give up waiting. The default timeout is 10 seconds, it can be customized when creating the Client instance:

const client = new Client({
  contactPoints,
  localDataCenter,
  protocolOptions: { maxSchemaAgreementWaitSeconds: 20 }
});

After executing a statement, you can check whether schema agreement was successful or timed out:

client.execute('CREATE TABLE table1 (id int PRIMARY KEY)')
  .then(rs => {
    console.log(`Is schema in agreement? ${rs.info.isSchemaInAgreement}`);
  });

Additionally, you can perform an on-demand check at any time:

client.metadata.checkSchemaAgreement()
  .then(agreement => {
    console.log(`Is schema in agreement? ${agreement}`);
  });

Note that the on-demand check using checkSchemaAgreement() does not retry, it only queries system tables once.