Module riak_core_capability

This module implements a cluster capability system that tracks the modes supported by different nodes in the cluster and automatically determines the most preferred mode for each capability that is supported by all nodes.

Behaviours: gen_server.

Description

This module implements a cluster capability system that tracks the modes supported by different nodes in the cluster and automatically determines the most preferred mode for each capability that is supported by all nodes. The primary use of this system is to support seamless transitions between different node versions during a rolling upgrade -- such as speaking an old protocol while the cluster still contains older nodes, and then switching to a newer protocol after all nodes have been upgraded.

The capability system exposes a simple register and get API, that allows applications to register a given capability and set of supported modes, and then retrieve the current mode that has been safely negotiated across the cluster. The system also allows overriding negotiation through application environment variables (eg. in app.config).

To register a capability and set of supported modes: Use register/3 or register/4

To query the current negotiated capability: Use get/1 or get/2

The capability system implements implicit mode preference. When registering modes, the modes listed earlier in the list are preferred over modes listed later in the list.

Users can override capabilities by setting the override_capability app variable for the appropriate application. For example, to override the {riak_core, vnode_routing} capability, the user could add the following to riak_core section of app.config:

{override_capability, [{vnode_routing, [{use, some_mode}, {prefer, some_other_mode}] }] }

The two override parameters are use and prefer. The use parameter specifies a mode that will always be used for the given capability, ignoring negotiation. It is a forced override. The prefer parameter specifies a mode that will be used if safe across the entire cluster. This overrides the built-in mode preference, but still only selects the mode if safe. When both use and prefer are specified, use takes precedence.

There is no inherent upgrading/downgrading of protocols in this system. The system is designed with the assumption that all supported modes can be used at any time (even concurrently), and is concerned solely with selecting the most preferred mode common across the cluster at a given point in time.

Data Types

capability()

capability() = atom() | {atom(), atom()}

mode()

mode() = term()

registered()

registered() = [{capability(), #capability{supported = [mode()], default = mode(), legacy = any()}}]

Function Index

all/0Return a list of all negotiated capabilities.
code_change/3
get/1Query the current negotiated mode for a given capability, throwing an exception if the capability is unknown or the capability system is unavailable.
get/2Query the current negotiated mode for a given capability, returning Default if the capability system is unavailable.
handle_call/3
handle_cast/2
handle_info/2
init/1
make_capability/4 Make a capbility from a capability atom, a list of supported modes, the default mode, and a mapping from a legacy var to it's capabilities.
preferred_modes/4 Given my node's capabilities, my node's registered default modes, the list of application env overrides, and the current view of all node's supported capabilities, determine the most preferred mode for each capability that is supported by all nodes.
register/3Register a new capability providing a list of supported modes as well as the default value.
register/4Register a new capability providing a list of supported modes, the default mode, and an optional mapping of how a legacy application variable maps to different modes.
start_link/0
terminate/2
update_ring/1Add the local node's supported capabilities to the given ring.

Function Details

all/0

all() -> any()

Return a list of all negotiated capabilities

code_change/3

code_change(OldVsn, State, Extra) -> any()

get/1

get(Capability) -> any()

Query the current negotiated mode for a given capability, throwing an exception if the capability is unknown or the capability system is unavailable.

get/2

get(Capability, Default) -> any()

Query the current negotiated mode for a given capability, returning Default if the capability system is unavailable.

handle_call/3

handle_call(X1, From, State) -> any()

handle_cast/2

handle_cast(Msg, State) -> any()

handle_info/2

handle_info(Info, State) -> any()

init/1

init(X1) -> any()

make_capability/4

make_capability(Capability::capability(), Supported::[mode()], Default::mode(), Legacy::term()) -> {capability(), #capability{supported = [mode()], default = mode(), legacy = any()}}

Make a capbility from a capability atom, a list of supported modes, the default mode, and a mapping from a legacy var to it's capabilities.

preferred_modes/4

preferred_modes(MyCaps::[{capability(), [mode()]}], Capabilities::[{node(), [{capability(), [mode()]}]}], Registered::registered(), Override::[{capability(), [mode()]}]) -> [{capability(), mode()}]

Given my node's capabilities, my node's registered default modes, the list of application env overrides, and the current view of all node's supported capabilities, determine the most preferred mode for each capability that is supported by all nodes.

register/3

register(Capability, Supported, Default) -> any()

Register a new capability providing a list of supported modes as well as the default value. The order of modes in Supported determines the mode preference -- modes listed earlier are more preferred.

register/4

register(Capability, Supported, Default, LegacyVar) -> any()

Register a new capability providing a list of supported modes, the default mode, and an optional mapping of how a legacy application variable maps to different modes. The order of modes in Supported determines the mode preference -- modes listed earlier are more preferred.

start_link/0

start_link() -> any()

terminate/2

terminate(Reason, State) -> any()

update_ring/1

update_ring(Ring) -> any()

Add the local node's supported capabilities to the given ring. Currently used during the riak-admin join process


Generated by EDoc