summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFred Hebert <mononcqc@ferd.ca>2015-07-03 15:18:28 +0000
committerFred Hebert <mononcqc@ferd.ca>2015-07-03 15:24:11 +0000
commitf48340039f5e0f4e571dd26371576e1facec8d5b (patch)
tree7559d9bb0a38080f3fa58f754b299d2b37291fc5
parent59b4bb5dcf22e845483a82c5dd7a929cd9a317da (diff)
Run agent as current process & hibernate
This tries to reduce memory usage when running `rebar3 shell` by running the agent in the current process (and avoiding to copy state cross-boundaries), and using frequent hibernation after each run to force a full GC and compaction of the current process.
-rw-r--r--src/rebar_agent.erl4
-rw-r--r--src/rebar_prv_shell.erl12
2 files changed, 11 insertions, 5 deletions
diff --git a/src/rebar_agent.erl b/src/rebar_agent.erl
index 24ac626..dc45dcf 100644
--- a/src/rebar_agent.erl
+++ b/src/rebar_agent.erl
@@ -26,11 +26,11 @@ init(State) ->
handle_call({cmd, Command}, _From, State=#state{state=RState, cwd=Cwd}) ->
MidState = maybe_show_warning(State),
{Res, NewRState} = run(default, Command, RState, Cwd),
- {reply, Res, MidState#state{state=NewRState}};
+ {reply, Res, MidState#state{state=NewRState}, hibernate};
handle_call({cmd, Namespace, Command}, _From, State = #state{state=RState, cwd=Cwd}) ->
MidState = maybe_show_warning(State),
{Res, NewRState} = run(Namespace, Command, RState, Cwd),
- {reply, Res, MidState#state{state=NewRState}};
+ {reply, Res, MidState#state{state=NewRState}, hibernate};
handle_call(_Call, _From, State) ->
{noreply, State}.
diff --git a/src/rebar_prv_shell.erl b/src/rebar_prv_shell.erl
index 84ad723..3c6369a 100644
--- a/src/rebar_prv_shell.erl
+++ b/src/rebar_prv_shell.erl
@@ -90,9 +90,10 @@ shell(State) ->
%% their application masters never gets the new group leader (held in
%% their internal state)
maybe_boot_apps(State),
- rebar_agent:start_link(State),
- %% this call never returns (until user quits shell)
- timer:sleep(infinity).
+ simulate_proc_lib(),
+ true = register(rebar_agent, self()),
+ {ok, GenState} = rebar_agent:init(State),
+ gen_server:enter_loop(rebar_agent, [], GenState, {local, rebar_agent}, hibernate).
info() ->
"Start a shell with project and deps preloaded similar to~n'erl -pa ebin -pa deps/*/ebin'.~n".
@@ -145,6 +146,11 @@ maybe_boot_apps(State) ->
boot_apps(Apps)
end.
+simulate_proc_lib() ->
+ FakeParent = spawn_link(fun() -> timer:sleep(infinity) end),
+ put('$ancestors', [FakeParent]),
+ put('$initial_call', {rebar_agent, init, 1}).
+
setup_name(State) ->
{Opts, _} = rebar_state:command_parsed_args(State),
case {proplists:get_value(name, Opts), proplists:get_value(sname, Opts)} of