charmhelpers.core.reactive.bus

ExternalHandler A variant Handler for external executable actions (such as bash scripts).
Handler Class representing a reactive state handler.
StateWatch
all_states Assert that all desired_states are active
any_hook Assert that the currently executing hook matches one of the given patterns.
any_states Assert that any of the desired_states are active
discover Discover handlers based on convention.
dispatch Dispatch registered handlers.
get_state Return the value associated with an active state, or None
get_states Return a mapping of all active states to their values
remove_state Remove / deactivate a state
set_state Set the given state as active, optionally associating with a relation
class charmhelpers.core.reactive.bus.ExternalHandler(filepath)

Bases: charmhelpers.core.reactive.bus.Handler

A variant Handler for external executable actions (such as bash scripts).

External handlers must adhere to the following protocol:

  • The handler can be any executable
  • When invoked with the --test command-line flag, it should exit with an exit code of zero to indicate that the handler should be invoked, and a non-zero exit code to indicate that it need not be invoked. It can also provide a line of output to be passed to the --invoke call, e.g., to indicate which sub-handlers should be invoked. The handler should not perform its action when given this flag.
  • When invoked with the --invoke command-line flag (which will be followed by any output returned by the --test call), the handler should perform its action(s).
id()
invoke()

Call the external handler to be invoked.

classmethod register(filepath)
test()

Call the external handler to test whether it should be invoked.

class charmhelpers.core.reactive.bus.Handler(action)

Bases: object

Class representing a reactive state handler.

add_args(args)

Add arguments to be passed to the action when invoked.

Parameters:args – Any sequence or iterable, which will be lazily evaluated to provide args. Subsequent calls to add_args() can be used to add additional arguments.
add_predicate(predicate)

Add a new predicate callback to this handler.

classmethod clear()

Clear all registered handlers.

classmethod get(action)

Get or register a handler for the given action.

Parameters:
  • action (func) – Callback that is called when invoking the Handler
  • args_source (func) – Optional callback that generates args for the action
classmethod get_handlers()

Clear all registered handlers.

id()
invoke()

Invoke this handler.

test()

Check the predicate(s) and return True if this handler should be invoked.

class charmhelpers.core.reactive.bus.StateWatch

Bases: object

classmethod change(state)
classmethod commit()
classmethod iteration(i)
key = 'reactive.state_watch'
classmethod reset()
classmethod watch(watcher, states)
charmhelpers.core.reactive.bus.all_states(*desired_states)

Assert that all desired_states are active

charmhelpers.core.reactive.bus.any_hook(*hook_patterns)

Assert that the currently executing hook matches one of the given patterns.

Each pattern will match one or more hooks, and can use the following special syntax:

  • db-relation-{joined,changed} can be used to match multiple hooks (in this case, db-relation-joined and db-relation-changed).
  • {provides:mysql}-relation-joined can be used to match a relation hook by the role and interface instead of the relation name. The role must be one of provides, requires, or peer.
  • The previous two can be combined, of course: {provides:mysql}-relation-{joined,changed}
charmhelpers.core.reactive.bus.any_states(*desired_states)

Assert that any of the desired_states are active

charmhelpers.core.reactive.bus.discover()

Discover handlers based on convention.

Handlers will be loaded from the following directories and their subdirectories:

  • $CHARM_DIR/reactive/
  • $CHARM_DIR/hooks/reactive/
  • $CHARM_DIR/hooks/relations/

They can be Python files, in which case they will be imported and decorated functions registered. Or they can be executables, in which case they must adhere to the ExternalHandler protocol.

charmhelpers.core.reactive.bus.dispatch()

Dispatch registered handlers.

Handlers are dispatched according to the following rules:

  • Handlers are repeatedly tested and invoked in iterations, until the system settles into quiescence (that is, until no new handlers match to be invoked).
  • In the first iteration, @hook and @action handlers will be invoked, if they match.
  • In subsequent iterations, other handlers are invoked, if they match.
  • Added states will not trigger new handlers until the next iteration, to ensure that chained states are invoked in a predictable order.
  • Removed states will cause the current set of matched handlers to be re-tested, to ensure that no handler is invoked after its matching state has been removed.
  • Other than the guarantees mentioned above, the order in which matching handlers are invoked is undefined.
  • States are preserved between hook and action invocations, and all matching handlers are re-invoked for every hook and action. There are decorators and helpers to prevent unnecessary reinvocations, such as only_once().
charmhelpers.core.reactive.bus.get_state(state, default=None)

Return the value associated with an active state, or None

charmhelpers.core.reactive.bus.get_states()

Return a mapping of all active states to their values

charmhelpers.core.reactive.bus.remove_state(state)

Remove / deactivate a state

charmhelpers.core.reactive.bus.set_state(state, value=None)

Set the given state as active, optionally associating with a relation