hooks (hooks v3.0.0)

View Source

Generic hooks system for Erlang applications.

Overview

The hooks module provides a flexible and efficient hooks system that allows you to create extension points in your application. Hooks enable you to register multiple functions that will be called at specific points in your code, similar to events or callbacks but with more flexibility.

Features

  • Priority-based execution order
  • Multiple execution strategies (run, fold, all, all_till_ok, only)
  • Plugin system with automatic hook registration
  • Efficient storage using persistent_term
  • Support for deferred initialization

Examples

Basic Hook Registration

%% Register a hook function
ok = hooks:reg(on_user_login, my_module, log_login, 2, 10).

%% Run the hook
ok = hooks:run(on_user_login, [UserId, Timestamp]).

%% Unregister the hook
ok = hooks:unreg(on_user_login, my_module, log_login, 2).

Using Plugins

%% Enable a plugin that registers its own hooks
ok = hooks:enable_plugin(my_plugin).

%% Disable the plugin and unregister its hooks
ok = hooks:disable_plugin(my_plugin).

Different Execution Strategies

%% Run all hooks until one returns 'stop'
ok = hooks:run(before_save, [Data]).

%% Fold over hooks with an accumulator
Result = hooks:run_fold(transform_data, [Input], InitialAcc).

%% Get all results from all hooks
Results = hooks:all(validate_data, [Data]).

%% Run until one returns ok or {ok, Value}
case hooks:all_till_ok(authenticate, [User, Pass]) of
    ok -> authenticated;
    {ok, UserInfo} -> {authenticated, UserInfo};
    {error, Reasons} -> {failed, Reasons}
end.

Configuration

The hooks application supports the following configuration options:

  • {wait_for_proc, atom()} - Wait for a registered process before becoming ready

Since

1.0.0

Summary

Types

hook()

-type hook() :: {atom(), atom(), non_neg_integer()} | {atom(), atom(), non_neg_integer(), integer()}.

hookname()

-type hookname() :: any().

hooks()

-type hooks() :: [{hookname(), [hook()]}].

Functions

all(HookName, Args)

-spec all(HookName :: hookname(), Args :: list()) -> [any()].

all_till_ok(HookName, Args)

-spec all_till_ok(HookName :: hookname(), Args :: list()) -> ok | {ok, any()} | {error, term()}.

callback_mode()

code_change(OldVsn, StateName, State, Extra)

disable_plugin(Application)

-spec disable_plugin(Application :: atom()) -> ok.

enable_plugin(Application)

-spec enable_plugin(Application :: atom()) -> ok | {error, term()}.

enable_plugin(Application, Paths)

-spec enable_plugin(Application :: atom(), Paths :: [string()]) -> ok | {error, term()}.

find(HookName)

-spec find(HookName :: hookname()) -> {ok, [{atom(), atom()}]} | error.

handle_event(EventType, EventContent, State, Data)

init/1

mreg(Hooks)

-spec mreg(Hooks :: hooks()) -> ok | {error, term()}.

munreg(Hooks)

-spec munreg(Hooks :: hooks()) -> ok.

not_ready/3

only(HookName, Args)

-spec only(HookName :: hookname(), Args :: list()) -> any() | no_hook.

ready/3

reg(Module, Fun, Arity)

-spec reg(Module :: atom(), Fun :: atom(), Arity :: non_neg_integer()) -> ok | {error, term()}.

reg(HookName, Module, Fun, Arity)

-spec reg(HookName :: hookname(), Module :: atom(), Fun :: atom(), Arity :: non_neg_integer()) ->
             ok | {error, term()}.

Register a function for a specific hook name.

Parameters

  • HookName - The hook identifier
  • Module - The module containing the hook function
  • Fun - The function name
  • Arity - The function arity

Returns

  • ok - Registration successful
  • {error, term()} - Registration failed

Examples

%% Register a function for the 'before_save' hook
ok = hooks:reg(before_save, validator, check_data, 1).

Since

1.0.0

reg(HookName, Module, Fun, Arity, Priority)

-spec reg(HookName :: hookname(),
          Module :: atom(),
          Fun :: atom(),
          Arity :: non_neg_integer(),
          Priority :: integer()) ->
             ok | {error, term()}.

run(HookName, Args)

-spec run(HookName :: hookname(), Args :: list()) -> ok.

run_fold(HookName, Args, Acc)

-spec run_fold(HookName :: hookname(), Args :: list(), Acc :: any()) -> Acc2 :: any().

start_link()

terminate(Reason, StateName, State)

unreg(Module, Function, Arity)

-spec unreg(Module :: atom(), Function :: atom(), Arity :: non_neg_integer()) -> ok.

unreg(HookName, Module, Fun, Arity)

-spec unreg(HookName :: hookname(), Module :: atom(), Fun :: atom(), Arity :: non_neg_integer()) -> ok.

unreg(HookName, Module, Fun, Arity, Priority)

-spec unreg(HookName :: hookname(),
            Module :: atom(),
            Fun :: atom(),
            Arity :: non_neg_integer(),
            Priority :: integer()) ->
               ok.