Permalink
Browse files

Load additional types on start up

  • Loading branch information...
1 parent a6ba9cd commit 2168c93ce85cccbb893c90b011bcae599d86041f Magnus Klaar committed Apr 27, 2012
Showing with 92 additions and 3 deletions.
  1. +6 −1 src/mimetypes.erl
  2. +50 −0 src/mimetypes_loader.erl
  3. +3 −2 src/mimetypes_sup.erl
  4. +33 −0 test/mimetypes_tests.erl
View
7 src/mimetypes.erl
@@ -8,7 +8,7 @@
-export([dmodule/0, mmodule/0]).
%% API - multiple databases
--export([create/1, load/2]).
+-export([create/1, load/2, load/3]).
-export([ext_to_mimes/1, ext_to_mimes/2]).
-export([mime_to_exts/1, mime_to_exts/2]).
@@ -128,6 +128,11 @@ create(Database) when Database =/= default ->
load(Database, Mappings) ->
gen_server:call(?SERVER, {load, Database, Mappings}).
+%% @doc Load a set of extension-mimetype mappings.
+-spec load(term(), [{binary(), binary()}], infinity | integer()) -> ok.
+load(Database, Mappings, Timeout) ->
+ gen_server:call(?SERVER, {load, Database, Mappings}, Timeout).
+
%% @doc Return the set of known mimetypes of an extension.
%% @equiv ext_to_mimes(Extension, default)
View
50 src/mimetypes_loader.erl
@@ -0,0 +1,50 @@
+-module(mimetypes_loader).
+
+-export([start_link/0]).
+-export([load/1]).
+
+%% @doc Spawn a process to load configured mimetypes.
+start_link() ->
+ case load_sync_env() of
+ false -> {ok, proc_lib:spawn_link(?MODULE, load, [false])};
+ true -> proc_lib:start_link(?MODULE, load, [true])
+ end.
+
+%% @private
+load(Sync) ->
+ Timeout = load_timeout_env(),
+ List = load_types_env(),
+ load(Timeout, List),
+ case Sync of
+ false -> ignore;
+ true -> proc_lib:init_ack({ok, self()})
+ end.
+
+
+%% @private
+load(Timeout, [{Database, Types}|T]) ->
+ mimetypes:load(Database, Types, Timeout),
+ load(Timeout, T);
+load(_Timeout, []) ->
+ ok.
+
+%% @private
+load_timeout_env() ->
+ case application:get_env(mimetypes, load_timeout) of
+ undefined -> 5000;
+ {ok, Timeout} -> Timeout
+ end.
+
+%% @private
+load_sync_env() ->
+ case application:get_env(mimetypes, load_sync) of
+ undefined -> false;
+ {ok, Sync} -> Sync
+ end.
+
+%% @private
+load_types_env() ->
+ case application:get_env(mimetypes, load) of
+ undefined -> [];
+ {ok, List} -> List
+ end.
View
5 src/mimetypes_sup.erl
@@ -10,7 +10,7 @@
%% Helper macro for declaring children of supervisor
-define(CHILD(I, Type), {I, {I, start_link, []}, permanent, 5000, Type, [I]}).
-
+-define(TCHILD(I, Type), {I, {I, start_link, []}, transient, 5000, Type, [I]}).
%% ===================================================================
%% API functions
%% ===================================================================
@@ -24,6 +24,7 @@ start_link() ->
init([]) ->
{ok, { {one_for_one, 5, 10}, [
- ?CHILD(mimetypes, worker)
+ ?CHILD(mimetypes, worker),
+ ?TCHILD(mimetypes_loader, worker)
]} }.
View
33 test/mimetypes_tests.erl
@@ -76,3 +76,36 @@ extensions_test_() ->
[?_assertEqual(mimetypes:extensions([<<"unknown/ext">>]), [])
,?_assertEqual(mimetypes:extensions(<<"unknown/ext">>), [])
]}}.
+
+sync_loader_test_() ->
+ {setup,local,
+ fun() ->
+ application:load(mimetypes),
+ application:set_env(mimetypes, load, [
+ {default, [{<<"foo1">>, <<"bar1">>}]}]),
+ application:set_env(mimetypes, load_sync, true),
+ application:start(mimetypes)
+ end,
+ fun(_) -> application:stop(mimetypes) end,
+ [?_assertEqual([<<"bar1">>], mimetypes:ext_to_mimes(<<"foo1">>))]}.
+
+async_loader_test_() ->
+ {setup,local,
+ fun() ->
+ application:load(mimetypes),
+ application:set_env(mimetypes, load, [
+ {default, [{<<"foo2">>, <<"bar2">>}]}]),
+ application:set_env(mimetypes, load_sync, false),
+ application:start(mimetypes)
+ end,
+ fun(_) -> application:stop(mimetypes) end,
+ [{timeout, 10000, ?_test(async_loader_onstart())},
+ {timeout, 10000, ?_test(async_loader_wait())}
+ ]}.
+
+async_loader_onstart() ->
+ ?assertEqual(undefined, mimetypes:ext_to_mimes(<<"foo2">>)).
+
+async_loader_wait() ->
+ receive after 5000 -> ok end, %% @todo don't use an arbitrary time
+ ?assertEqual([<<"bar2">>], mimetypes:ext_to_mimes(<<"foo2">>)).

0 comments on commit 2168c93

Please sign in to comment.