hook v0.1.2 Hook behaviour

An interface to define and leverage runtime resolution.

Groups

Mappings are defined under group/0s. Hook defaults the group to be the calling process making process isolation of mappings frictionless. Any term can also be supplied as the group. Putting :foo under :bar in the :red group, than fetching it from the :blue group will fail.

Resolution

Starting with the calling process:

  1. does the process define a mapping for the term

    1.1. the term has been resolved

  2. does the process define fallbacks

    2.1. for each fallback in order: goto step 1

  3. does the process have ancestors

    3.1. for each ancestor in order: goto step 1

  4. the term has not been resolved

Performance

In general, the thing to focus on with respect to performance is whether the function call is getting serialized through a GenServer or not. You will find that only calls that result in a write get serialized and those that only read do not.

Functions that get serialized through a GenServer:

Functions that do not get serialized through a GenServer:

This means that a "hot path" that is resolving a term via these functions should remain performant outside of extreme cases. ``

Link to this section Summary

Functions

Asserts that all non-infinity callbacks defined via Hook.callback/4 have been consumed.

Defines a callback that can be consumed count times.

Return group's callbacks.

Prepend group to the calling process' fallbacks.

Fetches the value for key for group.

Gets all values for group.

A macro that compiles into term itself or a Hook.fetch(term) call.

Puts value under key for group.

Resolves a callback for the calling process and executes it with args.

Link to this section Types

Link to this type

callback_opt()

callback_opt() :: {:group, group()} | {:count, count()}
Link to this type

callback_opts()

callback_opts() :: [callback_opt()]
Link to this type

count()

count() :: pos_integer() | :infinity
Link to this type

fun_key()

fun_key() :: {function_name :: atom(), arity :: non_neg_integer()}
Link to this type

group()

group() :: pid() | atom()

Link to this section Functions

Link to this function

assert(group \\ self())

Asserts that all non-infinity callbacks defined via Hook.callback/4 have been consumed.

Returns :ok or raises.

Link to this function

callback(module, function_name, function, opts \\ [])

Defines a callback that can be consumed count times.

Ensures a module value is put under the key module for the calling process.

Link to this function

callbacks(group \\ self())

Return group's callbacks.

Link to this function

fallback(src_group \\ self(), dest_group)

Prepend group to the calling process' fallbacks.

Link to this function

fetch(key, group \\ self())

Fetches the value for key for group.

Link to this function

fetch!(key, group \\ self())

See Hook.fetch/2.

Link to this function

get_all(group \\ self())

Gets all values for group.

Link to this macro

hook(term)

(macro)

A macro that compiles into term itself or a Hook.fetch(term) call.

By default the fetch call will only be used when the Mix environment is not :prod. This logic can be overidden by the :should_hook configuration:

config :hook,
  should_hook: {SomeModule, :some_function}

:should_hook will be called with a single argument that is a term being processed by the hook/1 macro and must return a boolean(). This evaluation will happen at compile time.

Link to this function

put(key, value, group \\ self())

Puts value under key for group.

Link to this function

resolve_callback(module, fun_key, args)

Resolves a callback for the calling process and executes it with args.

Link to this section Callbacks

Link to this callback

assert(group)

assert(group()) :: :ok
Link to this callback

callback(module, function_name, function, callback_opts)

callback(module(), function_name :: atom(), (... -> any()), callback_opts()) ::
  :ok
Link to this callback

callbacks(group)

callbacks(group()) :: %{
  resolved: [],
  unresolved: [{count(), pid(), function()}]
}
Link to this callback

fallback(dest, src)

fallback(dest :: group(), src :: group()) :: :ok
Link to this callback

fetch(key, group)

fetch(key :: any(), group()) :: {:ok, any()} | :error
Link to this callback

fetch!(any, group)

fetch!(any(), group()) :: any()
Link to this callback

get_all(group)

get_all(group()) :: {:ok, %{}} | :error
Link to this callback

put(from, to, group)

put(from :: module(), to :: module(), group()) :: :ok
Link to this callback

resolve_callback(module, fun_key, args)

resolve_callback(module(), fun_key(), args :: [any()]) :: any()