Skip to content
This repository has been archived by the owner. It is now read-only.
Permalink
Browse files
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
  • Loading branch information
iilyak committed Jun 24, 2015
1 parent 2530af3 commit 67612a641292de0da10cbe844a7d847983c316d4
Showing 3 changed files with 14 additions and 19 deletions.
@@ -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
@@ -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},
@@ -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,27 +99,27 @@ 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),
?_test(begin
?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], []))

0 comments on commit 67612a6

Please sign in to comment.