[erlang-questions] pattern to augment a release with a plugin system

Benoit Chesneau bchesneau@REDACTED
Sun Nov 29 22:04:27 CET 2015


On Fri, Nov 27, 2015 at 6:04 AM Ulf Wiger <ulf.wiger@REDACTED> wrote:

>
> On 26 Nov 2015, at 02:37, Benoit Chesneau <bchesneau@REDACTED> wrote:
>
> Are there other ways to do it? What would be the right pattern to do it?
> To be honest I am balancing between 2 and 3. 4 would be fine but would mean
> rewriting something similar to the release_handler.
>
> Generally speaking how people feels about augmenting dynamically a release
> with new applications/modules ?
>
>
> I’ve been using setup [1] to manage plugins, where each plugin is an
> application which you e.g. can copy into a designated plugin directory.
>
> The code could look like this:
>
> load_plugins() ->
>     AllPlugins = find_plugins(),
>     load_apps(AllPlugins),
>     register_plugins(AllPlugins),
>     start_apps(AllPlugins),
>     {ok, [A || {A,_} <- AllPlugins]}.
>
> find_plugins() ->
>     LibDirs = setup:lib_dirs("ERL_SETUP_LIBS"),
>     AppNames = app_names(LibDirs),
>     [{A,setup:pick_vsn(A, setup:find_app(A, LibDirs), latest)} ||
>         A <- AppNames].
>
> load_apps(AllPlugins) ->
>     lists:foreach(
>       fun({A,{V,D}}) ->
>               true = setup:patch_app(A, V, [D]),
>               ReloadRes = setup:reload_app(A, V, [D]),
>               ?debug("reload_app(~p, ~p, ~p) -> ~p~n", [A,V,[D],
> ReloadRes])
>       end, AllPlugins).
>
> register_plugins(AllPlugins) ->
>     … % provide system-specific code
>
> start_apps(AllPlugins) ->
>     lists:foreach(
>       fun({A, _}) ->
>               maybe_start(A)
>       end, AllPlugins).
>
> maybe_start(App) ->
>     case application:get_key(App, mod) of
>         {ok, {_, _}} ->
>             %% Can be started
>             application:start(App);
>         _ ->
>             ok
>     end.
>
> Setup can also help during upgrade, since when you call
> setup:reload_app/1, setup can automatically generate upgrade scripts to
> transition from a previous version of the app to the newest.
>
> Another possibly useful feature is that setup can generate new boot
> scripts from what’s currently running, with setup:keep_release(SystemVsn).
> Not that it was really intented for this scenario, but rather as an easy
> way to get started.
>
> BR,
> Ulf W
>


Thanks!

I did to some experiment this week-end using `setup` and so far I am very
pleased by what I see. The thing I am currently working on is the
"uninstall" action. So far I don't see any code for it in setup (which
sounds logical).  I do the easy for now :

uninstall(myplugin) ->
    application:stop(myplugin),
    application:stop(myplugin),
    remove_path(myplugin).

The remove_path function is inspired from the one in setup but not exposed.

Although that's the easy way. I probably need to manage possible
dependencies. My idea for it is parsing each .app and maintain the
relations between each apps. WHich would allows me to stop them as well if
they have no more relations.

Anyway, I will work more on that topic over the week and come back with
some code asap :) Thanks again for your code!

- benoit
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://erlang.org/pipermail/erlang-questions/attachments/20151129/5b039418/attachment.htm>


More information about the erlang-questions mailing list