Permalink
Browse files

Do initial plugin loading with the plugin manager.

We were running into issues where since the plugins were loaded after
the applicaiton was started, the data source manager couldn't actually
start the plugin-based data sources because they weren't laoded yet.
This modifies the main supervisor to start the plugin manager first, so
that the plugins are loaded right away, and the data source manager
follows at some point and has access to the plugin modules.
  • Loading branch information...
1 parent 2571ad6 commit 9d7d23f964aa2386d1998ca43a81e21a7817a0db @mitchellh committed Jun 7, 2012
View
@@ -1,4 +1,5 @@
deps/
+dev/
dist/
ebin/
rel/lifeguard/
View
@@ -18,6 +18,9 @@ devrel: rel
rm -rf rel/$(APP)/lib/$(APP)-*/priv
ln -sf $(abspath ./apps/$(APP)/priv) rel/$(APP)/lib/$(APP)-*
echo -s sync | tee -a rel/$(APP)/releases/*/vm.args
+ mkdir -p dev
+ test -f dev/sys.config || cp rel/$(APP)/releases/*/sys.config dev/
+ ln -sf $(abspath ./dev/sys.config) rel/$(APP)/releases/*/sys.config
rel: compile
./rebar generate -f
@@ -15,7 +15,7 @@
]},
{mod, { lifeguard_app, []}},
{env, [
- {data_sources, [{"garbage", lifeguard_ds_garbage, []}]},
+ {data_sources, []},
{http_ip, "0.0.0.0"},
{http_port, 5433},
{js_pending_limit, 128},
@@ -18,27 +18,8 @@ start(_StartType, _StartArgs) ->
lager:set_loglevel(lager_console_backend, list_to_atom(Value))
end,
- % Get the plugins we need to enable after starting the entire
- % supervision tree.
- {ok, Plugins} = application:get_env(plugins),
-
% Start the main supervisor, which kicks off the entire application process
- case lifeguard_sup:start_link() of
- {ok, _Pid} = GoodResult ->
- % The supervisor started up properly, so lets start up all
- % the plugins.
- lager:info("Enabling boot-up plugins: ~p", [Plugins]),
- lists:foreach(fun(Name) ->
- % XXX: Error handling
- lager:debug("Enabling boot-up plugin: ~p", [Name]),
- lifeguard_plugin_manager:enable_plugin(Name)
- end, Plugins),
-
- % And return the good result
- GoodResult;
- Other ->
- Other
- end.
+ lifeguard_sup:start_link().
stop(_State) ->
ok.
@@ -1,6 +1,6 @@
-module(lifeguard_plugin_manager).
-behavior(gen_server).
--export([start_link/1,
+-export([start_link/2,
enable_plugin/1]).
-export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2, code_change/3]).
@@ -9,15 +9,15 @@
}).
%% @doc Start the plugin manager.
-start_link(PluginPath) ->
+start_link(PluginPath, InitialPlugins) ->
% We require that the plugin path be a binary, so let's do our best
% to convert it, since user's enter it.
BinPluginPath = case lifeguard_util:to_binary(PluginPath) of
{ok, BinValue} -> BinValue;
{error, cant_convert} -> throw({not_binary, PluginPath})
end,
- gen_server:start_link({local, ?MODULE}, ?MODULE, [BinPluginPath], []).
+ gen_server:start_link({local, ?MODULE}, ?MODULE, [BinPluginPath, InitialPlugins], []).
%% @doc Load a plugin, which is just an OTP application, with
%% the given name.
@@ -28,21 +28,45 @@ enable_plugin(Plugin) ->
%% gen_server callbacks
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-init([PluginPath]) ->
+init([PluginPath, InitialPlugins]) ->
lager:info("Plugin manager started."),
+
+ % Start all the initial plugins
+ lists:foreach(fun(X) -> start_plugin(PluginPath, X) end, InitialPlugins),
+
+ % Booted!
{ok, #state{plugin_path=PluginPath}}.
handle_call({enable_plugin, Plugin}, _From, State) ->
PluginPath = State#state.plugin_path,
- PluginAtom = atom_to_binary(Plugin, utf8),
- RootPath = <<PluginPath/binary, "/", PluginAtom/binary>>,
+ Result = start_plugin(PluginPath, Plugin),
+ {reply, Result, State}.
+
+handle_cast(_Request, State) -> {noreply, State}.
+
+handle_info(_Request, State) -> {noreply, State}.
+
+terminate(_Reason, _State) -> ok.
+
+code_change(_OldVsn, State, _Extra) -> {ok, State}.
+
+%% ===================================================================
+%% Internal Methods
+%% ===================================================================
- Result = case filelib:is_dir(RootPath) of
+%% @doc Given a path to where plugins are stored and the name of a plugin,
+%% this will load the plugin, modify the code paths properly, and start the
+%% plugin as an OTP application.
+start_plugin(RootPath, Name) ->
+ PluginAtom = atom_to_binary(Name, utf8),
+ PluginRootPath = <<RootPath/binary, "/", PluginAtom/binary>>,
+
+ case filelib:is_dir(PluginRootPath) of
false -> {error, plugin_not_found};
true ->
% It exists, now we traverse all the lib paths and add it
% to the code paths. First, find all the libraries.
- LibPath = binary_to_list(<<RootPath/binary, "/lib/*/ebin">>),
+ LibPath = binary_to_list(<<PluginRootPath/binary, "/lib/*/ebin">>),
LibDirs = lists:filter(fun(X) -> filelib:is_dir(X) end, filelib:wildcard(LibPath)),
% Add every directory to the code path
@@ -52,15 +76,5 @@ handle_call({enable_plugin, Plugin}, _From, State) ->
end, LibDirs),
% Finally, start the application
- application:start(Plugin)
- end,
-
- {reply, Result, State}.
-
-handle_cast(_Request, State) -> {noreply, State}.
-
-handle_info(_Request, State) -> {noreply, State}.
-
-terminate(_Reason, _State) -> ok.
-
-code_change(_OldVsn, State, _Extra) -> {ok, State}.
+ application:start(Name)
+ end.
@@ -28,6 +28,7 @@ init([]) ->
{ok, JsPendingLimit} = application:get_env(js_pending_limit),
{ok, JsVMCount} = application:get_env(js_vm_count),
{ok, PluginPath} = application:get_env(plugin_path),
+ {ok, Plugins} = application:get_env(plugins),
{ok, StoragePath} = application:get_env(storage_path),
{ok, HTTPIP} = application:get_env(http_ip),
{ok, HTTPPort} = application:get_env(http_port),
@@ -54,7 +55,7 @@ init([]) ->
% Plugin manager
PluginManager = {plugin_manager,
- {lifeguard_plugin_manager, start_link, [PluginPath]},
+ {lifeguard_plugin_manager, start_link, [PluginPath, Plugins]},
permanent, 30000, worker, dynamic},
% Watch manager
@@ -68,5 +69,5 @@ init([]) ->
permanent, 30000, worker, dynamic},
% Return the full spec
- Children = [DSManager, JsManager, PluginManager, WatchManager, Web],
+ Children = [PluginManager, DSManager, JsManager, WatchManager, Web],
{ok, { {one_for_one, 5, 10}, Children} }.

0 comments on commit 9d7d23f

Please sign in to comment.