Use code_change to trigger generation of a module Previously we did periodic check of hashes for every provider module. We switch to code_change use. Which would be called if specify modules argument in child spec of the supervisor from where we register our provider module.
We rely on this bit "Modules should be a list with one element [Module], where Module is the name of the callback module, if the child process is a supervisor, gen_server or gen_fsm. If the child process is a gen_event, Modules should be dynamic." from http://www.erlang.org/doc/design_principles/sup_princ.html Project: http://git-wip-us.apache.org/repos/asf/couchdb-couch-epi/repo Commit: http://git-wip-us.apache.org/repos/asf/couchdb-couch-epi/commit/67612a64 Tree: http://git-wip-us.apache.org/repos/asf/couchdb-couch-epi/tree/67612a64 Diff: http://git-wip-us.apache.org/repos/asf/couchdb-couch-epi/diff/67612a64 Branch: refs/heads/master Commit: 67612a641292de0da10cbe844a7d847983c316d4 Parents: 2530af3 Author: ILYA Khlopotov <[email protected]> Authored: Wed Jun 24 14:09:16 2015 -0700 Committer: ILYA Khlopotov <[email protected]> Committed: Wed Jun 24 15:13:50 2015 -0700 ---------------------------------------------------------------------- src/couch_epi_functions.erl | 11 +++-------- src/couch_epi_server.erl | 2 +- test/couch_epi_functions_tests.erl | 20 ++++++++++---------- 3 files changed, 14 insertions(+), 19 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/couchdb-couch-epi/blob/67612a64/src/couch_epi_functions.erl ---------------------------------------------------------------------- diff --git a/src/couch_epi_functions.erl b/src/couch_epi_functions.erl index f86ca61..472934c 100644 --- a/src/couch_epi_functions.erl +++ b/src/couch_epi_functions.erl @@ -13,7 +13,6 @@ -module(couch_epi_functions). -behaviour(gen_server). --define(MONITOR_INTERVAL, 5000). %% ------------------------------------------------------------------ %% API Function Exports @@ -70,10 +69,8 @@ stop(Server) -> %% gen_server Function Definitions %% ------------------------------------------------------------------ -init([Provider, ServiceId, Modules, Options]) -> +init([Provider, ServiceId, Modules, _Options]) -> gen_server:cast(self(), init), - Interval = proplists:get_value(interval, Options, ?MONITOR_INTERVAL), - {ok, _Timer} = timer:send_interval(Interval, self(), tick), {ok, #state{ provider = Provider, modules = Modules, @@ -99,9 +96,6 @@ handle_cast(init, #state{pending = Pending} = State) -> handle_cast(_Msg, State) -> {noreply, State}. -handle_info(tick, State) -> - {_Res, NewState} = reload_if_updated(State), - {noreply, NewState}; handle_info(_Info, State) -> {noreply, State}. @@ -110,7 +104,8 @@ terminate(_Reason, State) -> ok. code_change(_OldVsn, State, _Extra) -> - {ok, State}. + {_, NewState} = reload_if_updated(State), + {ok, NewState}. %% ------------------------------------------------------------------ %% Internal Function Definitions http://git-wip-us.apache.org/repos/asf/couchdb-couch-epi/blob/67612a64/src/couch_epi_server.erl ---------------------------------------------------------------------- diff --git a/src/couch_epi_server.erl b/src/couch_epi_server.erl index e325db7..19d8eb4 100644 --- a/src/couch_epi_server.erl +++ b/src/couch_epi_server.erl @@ -86,7 +86,7 @@ handle_cast({notify, App, Key, OldData, Data}, handle_cast(_Msg, State) -> {noreply, State}. -handle_info({'DOWN', MonitorRef, Type, Object, Info}, +handle_info({'DOWN', MonitorRef, _Type, _Object, _Info}, #epi_server_state{subscriptions = Subscriptions0} = State0) -> Subscriptions1 = remove(Subscriptions0, MonitorRef), State1 = State0#epi_server_state{subscriptions = Subscriptions1}, http://git-wip-us.apache.org/repos/asf/couchdb-couch-epi/blob/67612a64/test/couch_epi_functions_tests.erl ---------------------------------------------------------------------- diff --git a/test/couch_epi_functions_tests.erl b/test/couch_epi_functions_tests.erl index c12b326..6b035b9 100644 --- a/test/couch_epi_functions_tests.erl +++ b/test/couch_epi_functions_tests.erl @@ -47,9 +47,8 @@ setup(Opts) -> ok = couch_epi_functions:wait(Pid), {Pid, Module, ServiceId, couch_epi_functions_gen:get_handle(ServiceId)}. -teardown({Pid, Module, _, Handle}) -> +teardown({Pid, Module, _, _Handle}) -> code:purge(Module), - %%code:purge(Handle), %% FIXME temporary hack couch_epi_functions:stop(Pid), catch meck:unload(compile), ok. @@ -58,10 +57,11 @@ generate_module(Name, Body) -> Tokens = couch_epi_codegen:scan(Body), couch_epi_codegen:generate(Name, Tokens). -temp_atom() -> - {A, B, C} = erlang:now(), - list_to_atom(lists:flatten(io_lib:format("module~p~p~p", [A, B, C]))). - +upgrade_release(Pid) -> + sys:suspend(Pid), + 'ok' = sys:change_code(Pid, couch_epi_functions, 'undefined', []), + sys:resume(Pid), + ok. epi_functions_test_() -> { @@ -99,19 +99,19 @@ ensure_reload_if_manually_triggered({Pid, Module, _ServiceId, _Handle}) -> ?assertMatch({error,{badmatch,{error,reload}}}, Result) end). -ensure_reload_if_changed({_Pid, Module, ServiceId, Handle}) -> +ensure_reload_if_changed({Pid, Module, ServiceId, _Handle}) -> ?_test(begin ?assertMatch( [{1, 2}], couch_epi_functions_gen:apply(ServiceId, foo, [1, 2], [])), ok = generate_module(Module, ?MODULE2(Module)), - timer:sleep(150), + upgrade_release(Pid), ?assertMatch( [3], couch_epi_functions_gen:apply(ServiceId, baz, [3], [])) end). -ensure_no_reload_when_no_change({_Pid, Module, ServiceId, Handle}) -> +ensure_no_reload_when_no_change({Pid, _Module, ServiceId, _Handle}) -> ok = meck:new(compile, [passthrough, unstick]), ok = meck:expect(compile, forms, fun(_, _) -> {error, compile_should_not_be_called} end), @@ -119,7 +119,7 @@ ensure_no_reload_when_no_change({_Pid, Module, ServiceId, Handle}) -> ?assertMatch( [{1, 2}], couch_epi_functions_gen:apply(ServiceId, foo, [1, 2], [])), - timer:sleep(200), + upgrade_release(Pid), ?assertMatch( [], couch_epi_functions_gen:apply(ServiceId, baz, [3], []))
