kura_capabilities behaviour (kura v2.0.6)

View Source

Capability flags for kura backends and pool implementations.

A module that participates in kura's backend story (today: the pool implementation; in 2.0 likely a dedicated backend aggregator) declares the capability set it supports by implementing the optional capabilities/0 callback. Consumers ask kura whether the running backend supports the features they need.

This makes "we don't support that on this backend" a boot error instead of a 3am pager. It is also the discipline that keeps the future multi-backend story honest: a non-SQL backend (Mnesia, Riak) will declare a small capability set, SQL-needing consumers will refuse to start, and there will be no runtime surprises.

Standard capabilities

The capability atom set is open — backends may declare custom flags and consumers may match against them. The standard atoms kura itself cares about:

  • returningINSERT/UPDATE/DELETE ... RETURNING
  • jsonbJSONB column type with operators
  • arrays — array column types
  • advisory_lockspg_advisory_lock family
  • listen_notifyLISTEN/NOTIFY pubsub
  • select_for_update_skip_lockedSELECT ... FOR UPDATE SKIP LOCKED
  • partial_indexesCREATE INDEX ... WHERE
  • transactionsBEGIN/COMMIT/ROLLBACK
  • savepointsSAVEPOINT/RELEASE/ROLLBACK TO
  • prepared_statements — server-side prepared statements

A module that does not implement capabilities/0 is treated as having the empty capability set. Anything it does support is opaque to kura.

Example

A consumer's supervisor refuses to start if PG-only features are missing:

init(_) ->
    case kura_capabilities:require(kura_pool_pgo, [returning, listen_notify]) of
        ok -> {ok, ...};
        {error, _} = Err -> Err
    end.

A backend declares its set:

-module(kura_pool_pgo).
-behaviour(kura_pool).

capabilities() ->
    [returning, jsonb, arrays, advisory_locks, listen_notify,
     select_for_update_skip_locked, partial_indexes, transactions,
     savepoints, prepared_statements].

Summary

Types

An open atom set. Backends may define custom capability atoms.

A list of capabilities a backend supports or a consumer requires.

Callbacks

Optional callback. Return the set of capabilities this module supports.

Functions

Return true if Module declares Cap.

Return ok if Module declares every capability in Required.

Return the capability set declared by Module.

Types

capability()

-type capability() :: atom().

An open atom set. Backends may define custom capability atoms.

capability_set()

-type capability_set() :: [capability()].

A list of capabilities a backend supports or a consumer requires.

Callbacks

capabilities()

(optional)
-callback capabilities() -> capability_set().

Optional callback. Return the set of capabilities this module supports.

Modules that do not implement this callback are treated as supporting nothing.

Functions

has(Module, Cap)

-spec has(module(), capability()) -> boolean().

Return true if Module declares Cap.

require(Module, Required)

-spec require(module(), capability_set()) -> ok | {error, {missing_capabilities, capability_set()}}.

Return ok if Module declares every capability in Required.

Otherwise return {error, {missing_capabilities, Missing}} listing the capabilities that the module did not declare. Intended to be called from a supervisor init so the application refuses to start on a backend that lacks required features.

supported(Module)

-spec supported(module()) -> capability_set().

Return the capability set declared by Module.

Returns [] if the module does not export capabilities/0.