Behaviours: gen_server.
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.
capability() = atom() | {atom(), atom()}
mode() = term()
registered() = [{capability(), #capability{supported = [mode()], default = mode(), legacy = any()}}]
| all/0 | Return a list of all negotiated capabilities. |
| code_change/3 | |
| get/1 | 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 | Query 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/3 | Register a new capability providing a list of supported modes as well as the default value. |
| register/4 | 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. |
| start_link/0 | |
| terminate/2 | |
| update_ring/1 | Add the local node's supported capabilities to the given ring. |
all() -> any()
Return a list of all negotiated capabilities
code_change(OldVsn, State, Extra) -> any()
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(Capability, Default) -> any()
Query the current negotiated mode for a given capability, returning
Default if the capability system is unavailable.
handle_call(X1, From, State) -> any()
handle_cast(Msg, State) -> any()
handle_info(Info, State) -> any()
init(X1) -> any()
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(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(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(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() -> any()
terminate(Reason, State) -> any()
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