Skip to content

Commit

Permalink
Merge pull request #322 from inaka/cabol.321.optional_callbacks
Browse files Browse the repository at this point in the history
[#321] In `sumo_store` add `handle_info` and `terminate` as optional callbacks
  • Loading branch information
Brujo Benavides authored Jul 19, 2017
2 parents 7461e69 + 9b4d3fc commit ca61dbd
Show file tree
Hide file tree
Showing 15 changed files with 298 additions and 60 deletions.
3 changes: 1 addition & 2 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
sudo: false
language: erlang
otp_release:
- 19.2
- 18.3
- 19.3
before_install:
- ./ci before_install "${PWD:?}"/rebar3
install:
Expand Down
41 changes: 41 additions & 0 deletions config/sys.config
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
[
{sumo_db, [
{wpool_opts, [{overrun_warning, 100}]},
{verbose, true},
{query_timeout, 30000},
{storage_backends, [
{sumo_test_backend_mnesia, sumo_backend_mnesia, []}
]},
{stores, [
{sumo_test_mnesia, sumo_store_mnesia, [
{workers, 10},
{ram_copies, here},
{majority, false}
]},
{sumo_test_store1, sumo_test_store1, [
{workers, 10},
{ram_copies, here},
{majority, false}
]},
{sumo_test_store2, sumo_test_store2, [
{workers, 10},
{ram_copies, here},
{majority, false}
]},
{sumo_test_store3, sumo_test_store3, [
{workers, 10},
{ram_copies, here},
{majority, false}
]}
]},
{docs, [
{people, sumo_test_mnesia, #{module => sumo_test_people_mnesia}},
{people1, sumo_test_store1, #{module => sumo_test_people_mnesia}},
{people2, sumo_test_store2, #{module => sumo_test_people_mnesia}},
{people3, sumo_test_store3, #{module => sumo_test_people_mnesia}}
]},
{events, [
{people, sumo_test_people_events_manager}
]}
]}
].
4 changes: 1 addition & 3 deletions rebar.config
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
strict_validation,
warn_export_vars,
warn_exported_vars,
warn_missing_spec,
warn_untyped_record,
debug_info
]}.
Expand Down Expand Up @@ -62,13 +61,12 @@
strict_validation,
warn_export_vars,
warn_exported_vars,
warn_missing_spec,
warn_untyped_record,
debug_info
]}.

{ct_opts, [
{sys_config, ["test/test.config"]}
{sys_config, ["config/sys.config"]}
]}.

%% == Cover ==
Expand Down
2 changes: 1 addition & 1 deletion src/sumo_backend_sup.erl
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ start_link() ->
%%% Supervisor callbacks
%%%=============================================================================

-spec init(any()) -> {ok, {supervisor:sup_flags(), [supervisor:child_spec()]}}.
%% hidden
init([]) ->
{ok, Backends} = application:get_env(sumo_db, storage_backends),
Children = lists:map(fun({Name, Module, Options}) ->
Expand Down
8 changes: 6 additions & 2 deletions src/sumo_event.erl
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,12 @@ dispatch(DocName, Event, Args) ->
dispatch(DocName, EventId, Event, Args).

%% @doc Dispatch an event through gen_event:notify/2.
-spec dispatch(sumo:schema_name(), event_id(), term(), term()) ->
event_id() | no_event_managers.
-spec dispatch(DocName, EventId, Event, Args) -> Res when
DocName :: sumo:schema_name(),
EventId :: event_id(),
Event :: term(),
Args :: term(),
Res :: event_id() | no_event_managers.
dispatch(DocName, EventId, Event, Args) ->
case sumo_config:get_event_managers(DocName) of
[] ->
Expand Down
2 changes: 1 addition & 1 deletion src/sumo_event_manager_sup.erl
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ start_link() -> supervisor:start_link({local, ?MODULE}, ?MODULE, []).
%%% Supervisor callbacks
%%%=============================================================================

-spec init(any()) -> {ok, {supervisor:sup_flags(), [supervisor:child_spec()]}}.
%% hidden
init([]) ->
EventManagers = sumo_config:get_event_managers(),
ManagersList = [manager(EventManager) || EventManager <- EventManagers],
Expand Down
82 changes: 58 additions & 24 deletions src/sumo_store.erl
Original file line number Diff line number Diff line change
Expand Up @@ -60,20 +60,34 @@
handler_state = undefined :: any()
}).

-type state() :: #state{}.

%%%=============================================================================
%%% Callbacks
%%%=============================================================================

-type result(R, S) :: {ok, R, S} | {error, term(), S}.
-type result(S) :: {ok, S} | {error, term(), S}.
-type affected_rows() :: unknown | non_neg_integer().

-export_type([result/2, result/1, affected_rows/0]).

%%%=============================================================================
%%% gen_server callbacks
%%%=============================================================================

-callback init(term()) -> {ok, term()}.

-callback handle_info(Info, State) -> Res when
Info :: term(),
State :: term(),
Res :: {noreply, State}
| {noreply, State, timeout()}
| {noreply, State, hibernate}
| {stop, Reason :: term(), State}.

-callback terminate(Reason, State) -> ok when
Reason :: normal | shutdown | {shutdown, term()} | term(),
State :: term().

%%%=============================================================================
%%% API callbacks
%%%=============================================================================

-callback create_schema(Schema, State) -> Res when
Schema :: sumo:schema(),
Res :: result(State).
Expand Down Expand Up @@ -136,6 +150,8 @@
Conditions :: sumo:conditions(),
Res :: result(non_neg_integer(), State).

-optional_callbacks([handle_info/2, terminate/2]).

%%%=============================================================================
%%% API
%%%=============================================================================
Expand Down Expand Up @@ -293,14 +309,12 @@ call(Name, DocName, Function, Args) ->

%% @doc Called by start_link.
%% @hidden
-spec init([term()]) -> {ok, state()}.
init([Module, Options]) ->
{ok, HState} = Module:init(Options),
{ok, #state{handler=Module, handler_state=HState}}.

%% @doc handles calls.
%% @hidden
-spec handle_call(term(), _, state()) -> {reply, tuple(), state()}.
handle_call(
{create_schema, Schema}, _From,
#state{handler = Handler, handler_state = HState} = State
Expand Down Expand Up @@ -403,29 +417,49 @@ handle_call(
{reply, {OkOrError, Reply}, State#state{handler_state=NewState}}.

%% @hidden
-spec handle_cast(term(), state()) ->
{noreply, state()} |
{noreply, state(), non_neg_integer()} |
{noreply, state(), hibernate} |
{stop, term(), state()}.
handle_cast(_Msg, State) ->
{noreply, State}.

%% @hidden
-spec handle_info(term(), state()) ->
{noreply, state()} |
{noreply, state(), non_neg_integer()} |
{noreply, state(), hibernate} |
{stop, term(), state()}.
handle_info(_Info, State) ->
{noreply, State}.
handle_info(Info, #state{handler = Handler, handler_state = HState} = State) ->
case erlang:function_exported(Handler, handle_info, 2) of
true ->
try Handler:handle_info(Info, HState) of
Response -> handle_info_response(Response, State)
catch
throw:Response -> handle_info_response(Response, State)
end;
false ->
{noreply, State}
end.

%% @hidden
-spec terminate(term(), state()) -> ok.
terminate(_Reason, _State) ->
ok.
terminate(Reason, #state{handler = Handler, handler_state = HState}) ->
case erlang:function_exported(Handler, terminate, 2) of
true ->
try
Handler:terminate(Reason, HState)
catch
throw:Response -> Response
end;
false ->
ok
end.

%% @hidden
-spec code_change(term(), state(), term()) -> {ok, state()} | {error, term()}.
code_change(_OldVsn, State, _Extra) ->
{ok, State}.

%%%=============================================================================
%%% Internal Functions
%%%=============================================================================

%% @private
handle_info_response({noreply, NewHState}, State) ->
{noreply, State#state{handler_state = NewHState}};
handle_info_response({noreply, NewHState, hibernate}, State) ->
{noreply, State#state{handler_state = NewHState}, hibernate};
handle_info_response({noreply, NewHState, Timeout}, State) ->
{noreply, State#state{handler_state = NewHState}, Timeout};
handle_info_response({stop, Reason, NewHState}, State) ->
{stop, Reason, State#state{handler_state = NewHState}}.
2 changes: 1 addition & 1 deletion src/sumo_store_sup.erl
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ start_link() ->
%%% Supervisor callbacks
%%%=============================================================================

-spec init(any()) -> {ok, {supervisor:sup_flags(), [supervisor:child_spec()]}}.
%% @hidden
init([]) ->
{ok, Stores} = application:get_env(sumo_db, stores),
Children = lists:map(fun({Name, Module, Options}) ->
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
-module(conditional_logic_SUITE).
-module(sumo_conditionals_SUITE).

%% CT
-export([
Expand Down
9 changes: 7 additions & 2 deletions test/sumo_meta_SUITE.erl
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,14 @@
]}
]).

-export([init_per_suite/1]).
-export([init_per_suite/1, end_per_suite/1]).

-type config() :: [{atom(), term()}].

-spec init_per_suite(config()) -> config().
init_per_suite(Config) -> [{application, sumo_db} | Config].
init_per_suite(Config) ->
[{application, sumo_db} | Config].

-spec end_per_suite(config()) -> config().
end_per_suite(Config) ->
Config.
67 changes: 67 additions & 0 deletions test/sumo_optional_callbacks_SUITE.erl
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
-module(sumo_optional_callbacks_SUITE).

-include_lib("common_test/include/ct.hrl").

%% CT
-export([
all/0,
init_per_suite/1,
end_per_suite/1
]).

%% Test Cases
-export([
t_optional_callbacks/1
]).

-define(EXCLUDED_FUNS, [
module_info,
all,
init_per_suite,
end_per_suite
]).

%%%=============================================================================
%%% Common Test
%%%=============================================================================

%% @hidden
all() ->
Exports = ?MODULE:module_info(exports),
[F || {F, _} <- Exports, not lists:member(F, ?EXCLUDED_FUNS)].

%% @hidden
init_per_suite(Config) ->
ok = sumo_test_utils:start_apps(),
[{schemas, [people1, people2, people3]} | Config].

%% @hidden
end_per_suite(Config) ->
_ = application:stop(sumo_db),
Config.

%%%=============================================================================
%%% Test Cases
%%%=============================================================================

%% @hidden
t_optional_callbacks(Config) ->
run_for_all_schemas(Config, fun t_optional_callbacks_/1).

%% @hidden
t_optional_callbacks_(SchemaName) ->
_ = sumo:call(SchemaName, send_msg, [noreply]),
_ = sumo:call(SchemaName, send_msg, [hibernate]),
_ = sumo:call(SchemaName, send_msg, [timeout]),
_ = sumo:call(SchemaName, send_msg, [stop]),
_ = sumo:call(SchemaName, send_msg, [throw]),
ok.

%%%=============================================================================
%%% Internal Functions
%%%=============================================================================

%% @private
run_for_all_schemas(Config, Fun) ->
{_, Schemas} = lists:keyfind(schemas, 1, Config),
lists:foreach(Fun, Schemas).
43 changes: 43 additions & 0 deletions test/support/sumo_test_store1.erl
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
-module(sumo_test_store1).

-behaviour(sumo_store).

%% @todo remove this once mixer migrates specs better
-dialyzer([no_behaviours]).

-include_lib("mixer/include/mixer.hrl").
-mixin([
{sumo_store_mnesia, [
init/1,
create_schema/2,
persist/2,
fetch/3,
delete_by/3,
delete_all/2,
find_all/2, find_all/5,
find_by/3, find_by/5, find_by/6,
count/2,
count_by/3
]}
]).

-export([send_msg/3]).

%% @hidden
send_msg(noreply, _DocName, State) ->
{ok, {raw, send({noreply, State})}, State};
send_msg(hibernate, _DocName, State) ->
{ok, {raw, send({noreply, State, hibernate})}, State};
send_msg(timeout, _DocName, State) ->
{ok, {raw, send({noreply, State, 1})}, State};
send_msg(stop, DocName, State) ->
{ok, {raw, send({stop, DocName, State})}, State};
send_msg(throw, _DocName, State) ->
{ok, {raw, send(throw)}, State};
send_msg(terminate, _DocName, State) ->
{ok, {raw, send(terminate)}, State}.

%% @private
send(Msg) ->
self() ! Msg,
ok.
Loading

0 comments on commit ca61dbd

Please sign in to comment.