Browse Source

refactor settings, use application get/set _env instead of epgsql_pool_settings.erl

Yuriy Zhloba 9 years ago
parent
commit
47e4ee626e

+ 17 - 11
src/epgsql_pool.app.src

@@ -1,13 +1,19 @@
 %%-*- mode: erlang -*-
 
-{application, epgsql_pool, [
-    {description, "Connection pool for PostgreSQL"},
-    {vsn, "1.0.0"},
-    {registered, []},
-    {applications, [
-        epgsql,
-        pooler
-    ]},
-    {mod, {epgsql_pool_app, []}},
-    {env, []}
-]}.
+{application, epgsql_pool,
+ [
+  {description, "Connection pool for PostgreSQL"},
+  {vsn, "1.0.0"},
+  {registered, []},
+  {applications, [epgsql, pooler]},
+  {mod, {epgsql_pool_app, []}},
+  {env, [
+         {connection_timeout, 10000},
+         {query_timeout, 10000},
+         {pooler_get_worker_timeout, 10000},
+         {pooler_max_queue, 100},
+         {max_reconnect_timeout, 5000},
+         {min_reconnect_timeout, 100},
+         {keep_alive_timeout, 60000}
+        ]}
+ ]}.

+ 19 - 9
src/epgsql_pool.erl

@@ -28,8 +28,9 @@ start(PoolName, InitCount, MaxCount, ConnectionParams) when is_map(ConnectionPar
 
 start(PoolName0, InitCount, MaxCount, #epgsql_connection_params{} = ConnectionParams) ->
     PoolName = epgsql_pool_utils:pool_name_to_atom(PoolName0),
-    epgsql_pool_settings:set_connection_params(PoolName, ConnectionParams),
-    MaxQueue = epgsql_pool_settings:get(pooler_max_queue),
+    %% TODO check PoolName not in all_keys()
+    application:set_env(epgsql_pool, PoolName, ConnectionParams),
+    {ok, MaxQueue} = application:get_env(epgsql_pool, pooler_max_queue),
     PoolConfig = [{name, PoolName},
                   {init_count, InitCount},
                   {max_count, MaxCount},
@@ -58,7 +59,7 @@ validate_connection_params(ConnectionParams) when is_map(ConnectionParams) ->
 
 validate_connection_params(#epgsql_connection_params{host = Host, port = Port, username = Username,
                                                      password = Password, database = Database}) ->
-    ConnectionTimeout = epgsql_pool_settings:get(connection_timeout),
+    {ok,ConnectionTimeout} = application:get_env(epgsql_pool, connection_timeout),
     Res = epgsql:connect(Host, Username, Password,
                          [{port, Port},
                           {database, Database},
@@ -82,7 +83,7 @@ query(PoolNameOrWorker, Stmt, Params) ->
 -spec query(pool_name() | pid(), epgsql:sql_query(), [epgsql:bind_param()], [proplists:option()]) -> epgsql:reply().
 query(Worker, Stmt, Params, Options) when is_pid(Worker) ->
     Timeout = case proplists:get_value(timeout, Options) of
-                  undefined -> epgsql_pool_settings:get(query_timeout);
+                  undefined -> element(2, application:get_env(epgsql_pool, query_timeout));
                   V -> V
               end,
     Sock = gen_server:call(Worker, get_sock),
@@ -135,24 +136,26 @@ transaction(PoolName0, Fun) ->
 -spec get_settings() -> map().
 get_settings() ->
     lists:foldl(fun(Key, Map) ->
-                        maps:put(Key, epgsql_pool_settings:get(Key), Map)
-                end, maps:new(), epgsql_pool_settings:all_keys()).
+                        maps:put(Key, element(2, application:get_env(epgsql_pool, Key)), Map)
+                end, maps:new(), all_keys()).
 
 
 -spec set_settings(map()) -> ok.
 set_settings(Map) ->
     lists:foreach(fun(Key) ->
                           case maps:find(Key, Map) of
-                              {ok, Value} -> epgsql_pool_settings:set(Key, Value);
+                              {ok, Value} -> application:set_env(epgsql_pool, Key, Value);
                               error -> do_nothing
                           end
-                  end, epgsql_pool_settings:all_keys()),
+                  end, all_keys()),
     ok.
 
+
 %%% inner functions
 
+-spec get_worker(pool_name()) -> {ok, pid()} | {error, term()}.
 get_worker(PoolName) ->
-    Timeout = epgsql_pool_settings:get(pooler_get_worker_timeout),
+    {ok, Timeout} = application:get_env(epgsql_pool, pooler_get_worker_timeout),
     case pooler:take_member(PoolName, Timeout) of
         Worker when is_pid(Worker) -> {ok, Worker};
         error_no_members ->
@@ -160,3 +163,10 @@ get_worker(PoolName) ->
             error_logger:error_msg("Pool ~p overload: ~p", [PoolName, PoolStats]),
             {error, pool_overload}
     end.
+
+
+-spec all_keys() -> [atom()].
+all_keys() ->
+    [connection_timeout, query_timeout,
+     pooler_get_worker_timeout, pooler_max_queue,
+     max_reconnect_timeout, min_reconnect_timeout, keep_alive_timeout].

+ 1 - 1
src/epgsql_pool_app.erl

@@ -9,7 +9,7 @@
 
 -spec start(term(), term()) -> {ok, pid()}.
 start(_StartType, _StartArgs) ->
-    epgsql_pool_sup:start_link().
+    {ok, self()}.
 
 
 -spec stop(term()) -> ok.

+ 0 - 103
src/epgsql_pool_settings.erl

@@ -1,103 +0,0 @@
--module(epgsql_pool_settings).
--behavior(gen_server).
-
--export([start_link/0,
-         get_connection_params/1,
-         set_connection_params/2,
-         get/1, set/2, all_keys/0]).
--export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2, code_change/3]).
-
--include("epgsql_pool.hrl").
--include("otp_types.hrl").
-
-
-%%% module API
-
--spec start_link() -> gs_start_link_reply().
-start_link() ->
-    gen_server:start_link({local, ?MODULE}, ?MODULE, [], []).
-
-
--spec get_connection_params(epgsql_pool:pool_name()) -> {ok, #epgsql_connection_params{}} | {error, not_found}.
-get_connection_params(PoolName) ->
-    Key = {connection, epgsql_pool_utils:pool_name_to_atom(PoolName)},
-    case ets:lookup(?MODULE, Key) of
-        [] -> {error, not_found};
-        [{{connection, PoolName}, ConnectionParams}] -> {ok, ConnectionParams}
-    end.
-
-
--spec set_connection_params(egpsql_pool:pool_name(), #epgsql_connection_params{}) -> ok.
-set_connection_params(PoolName, Params) ->
-    Key = {connection, epgsql_pool_utils:pool_name_to_atom(PoolName)},
-    gen_server:call(?MODULE, {save, Key, Params}).
-
-
--spec get(atom()) -> integer().
-get(Key) ->
-    case ets:lookup(?MODULE, {settings, Key}) of
-        [] -> throw({settings_not_found, Key});
-        [{_, Value}] -> Value
-    end.
-
-
--spec set(atom(), integer()) -> ok.
-set(Key, Value) ->
-    gen_server:call(?MODULE, {save, {settings, Key}, Value}).
-
-
--spec all_keys() -> [atom()].
-all_keys() ->
-    [connection_timeout, query_timeout,
-     pooler_get_worker_timeout, pooler_max_queue,
-     max_reconnect_timeout, min_reconnect_timeout, keep_alive_timeout].
-
-
-%%% gen_server API
-
--spec init(gs_args()) -> gs_init_reply().
-init([]) ->
-    T = ets:new(?MODULE, [protected, named_table]),
-    ets:insert(T, {{settings, connection_timeout}, 10000}),
-    ets:insert(T, {{settings, query_timeout}, 10000}),
-    ets:insert(T, {{settings, pooler_get_worker_timeout}, 10000}),
-    ets:insert(T, {{settings, pooler_max_queue}, 100}),
-    ets:insert(T, {{settings, max_reconnect_timeout}, 5000}),
-    ets:insert(T, {{settings, min_reconnect_timeout}, 100}),
-    ets:insert(T, {{settings, keep_alive_timeout}, 60000}),
-    {ok, T}.
-
-
--spec handle_call(gs_request(), gs_from(), gs_reply()) -> gs_call_reply().
-handle_call({save, Key, Value}, _From, Table) ->
-    ets:insert(Table, {Key, Value}),
-    {reply, ok, Table};
-
-handle_call(Any, _From, State) ->
-    error_logger:error_msg("unknown call ~p in ~p ~n", [Any, ?MODULE]),
-    {noreply, State}.
-
-
--spec handle_cast(gs_request(), gs_state()) -> gs_cast_reply().
-handle_cast(Any, State) ->
-    error_logger:error_msg("unknown cast ~p in ~p ~n", [Any, ?MODULE]),
-    {noreply, State}.
-
-
--spec handle_info(gs_request(), gs_state()) -> gs_info_reply().
-handle_info(stop, State) ->
-    {stop, normal, State};
-
-handle_info(Request, State) ->
-    error_logger:error_msg("unknown info ~p in ~p ~n", [Request, ?MODULE]),
-    {noreply, State}.
-
-
--spec terminate(terminate_reason(), gs_state()) -> ok.
-terminate(_Reason, _State) ->
-    ok.
-
-
--spec code_change(term(), term(), term()) -> gs_code_change_reply().
-code_change(_OldVersion, State, _Extra) ->
-    {ok, State}.

+ 0 - 33
src/epgsql_pool_sup.erl

@@ -1,33 +0,0 @@
--module(epgsql_pool_sup).
--behaviour(supervisor).
-
--export([start_link/0, init/1]).
-
--include("otp_types.hrl").
-
-
--spec(start_link() -> {ok, pid()}).
-start_link() ->
-    supervisor:start_link({local, ?MODULE}, ?MODULE, []).
-
-
--spec(init(gs_args()) -> sup_init_reply()).
-init(_Args) ->
-    RestartStrategy = one_for_one, % one_for_one | one_for_all | rest_for_one
-    Intensity = 10, %% max restarts
-    Period = 60, %% in period of time
-    SupervisorSpecification = {RestartStrategy, Intensity, Period},
-
-    Restart = permanent, % permanent | transient | temporary
-    Shutdown = 2000, % milliseconds | brutal_kill | infinity
-
-    ChildSpecifications =
-        [
-         {epgsql_pool_settings,
-          {epgsql_pool_settings, start_link, []},
-          Restart,
-          Shutdown,
-          worker,
-          [epgsql_pool_settings]}
-        ],
-    {ok, {SupervisorSpecification, ChildSpecifications}}.

+ 6 - 5
src/epgsql_pool_utils.erl

@@ -9,14 +9,15 @@
 -include("epgsql_pool.hrl").
 
 
--spec open_connection(atom(), #epgsql_connection{} | undefined) -> {ok, #epgsql_connection{}} | {error, term(), #epgsql_connection{}}.
+-spec open_connection(atom(), #epgsql_connection{} | undefined) ->
+                             {ok, #epgsql_connection{}} | {error, term(), #epgsql_connection{}}.
 open_connection(PoolName, undefined) ->
     open_connection(PoolName, #epgsql_connection{});
 open_connection(PoolName, Connection0) ->
-    {ok,Params} = epgsql_pool_settings:get_connection_params(PoolName),
+    {ok, Params} = application:get_env(epgsql_pool, PoolName),
     #epgsql_connection_params{host = Host, port = Port, username = Username,
                               password = Password, database = Database} = Params,
-    ConnectionTimeout = epgsql_pool_settings:get(connection_timeout),
+    {ok, ConnectionTimeout} = application:get_env(epgsql_pool, connection_timeout),
     Res = epgsql:connect(Host, Username, Password,
                          [{port, Port},
                           {database, Database},
@@ -37,8 +38,8 @@ close_connection(#epgsql_connection{sock = Sock} = Connection) ->
 
 -spec reconnect(#epgsql_connection{}) -> #epgsql_connection{}.
 reconnect(#epgsql_connection{reconnect_attempt = Attempt} = Connection) ->
-    MaxTimeout = epgsql_pool_settings:get(max_reconnect_timeout),
-    MinTimeout = epgsql_pool_settings:get(min_reconnect_timeout),
+    {ok, MaxTimeout} = application:get_env(epgsql_pool, max_reconnect_timeout),
+    {ok, MinTimeout} = application:get_env(epgsql_pool, min_reconnect_timeout),
     Timeout = exponential_backoff(Attempt, 10, MinTimeout, MaxTimeout),
     error_logger:warning_msg("epgsql_pool reconnect after ~p attempt ~p", [Timeout, Attempt]),
     erlang:send_after(Timeout, self(), open_connection),

+ 3 - 3
src/epgsql_pool_worker.erl

@@ -97,7 +97,7 @@ handle_info(open_connection, #state{pool_name = PoolName, connection = Connectio
                                     send_keep_alive_timer = Send_KA_Timer} = State) ->
     case epgsql_pool_utils:open_connection(PoolName, Connection) of
         {ok, Connection2} ->
-            KeepAliveTimeout = epgsql_pool_settings:get(keep_alive_timeout),
+            {ok, KeepAliveTimeout} = application:get_env(epgsql_pool, keep_alive_timeout),
             erlang:cancel_timer(Send_KA_Timer),
             Send_KA_Timer2 = erlang:send_after(KeepAliveTimeout, self(), keep_alive),
             {noreply, State#state{connection = Connection2, send_keep_alive_timer = Send_KA_Timer2}};
@@ -116,7 +116,7 @@ handle_info(keep_alive, #state{connection = #epgsql_connection{sock = Sock},
     %% send async keep-alive query to DB
     KA_Ref = epgsqli:squery(Sock, <<"SELECT 1">>),
 
-    QueryTimeout = epgsql_pool_settings:get(query_timeout),
+    {ok, QueryTimeout} = application:get_env(epgsql_pool, query_timeout),
     erlang:cancel_timer(NR_KA_Timer),
     NR_KA_Timer2 = erlang:send_after(QueryTimeout, self(), no_reply_to_keep_alive),
     {noreply, State#state{keep_alive_query_ref = KA_Ref, no_reply_keep_alive_timer = NR_KA_Timer2}};
@@ -125,7 +125,7 @@ handle_info({_Pid, Ref, done}, #state{keep_alive_query_ref = Ref,
                                       send_keep_alive_timer = Send_KA_Timer,
                                       no_reply_keep_alive_timer = NR_KA_Timer} = State) ->
     %% got reply to asycn keep-alive query from DB
-    KeepAliveTimeout = epgsql_pool_settings:get(keep_alive_timeout),
+    {ok, KeepAliveTimeout} = application:get_env(epgsql_pool, keep_alive_timeout),
     erlang:cancel_timer(Send_KA_Timer),
     erlang:cancel_timer(NR_KA_Timer),
     Send_KA_Timer2 = erlang:send_after(KeepAliveTimeout, self(), keep_alive),

+ 0 - 49
test/epgsql_pool_settings_tests.erl

@@ -1,49 +0,0 @@
--module(epgsql_pool_settings_tests).
-
--include("epgsql_pool.hrl").
--include_lib("eunit/include/eunit.hrl").
-
-
-get_set_test() ->
-    epgsql_pool_settings:start_link(),
-
-    ?assertEqual(10000, epgsql_pool_settings:get(connection_timeout)),
-    ?assertEqual(10000, epgsql_pool_settings:get(query_timeout)),
-    ?assertEqual(10000, epgsql_pool_settings:get(pooler_get_worker_timeout)),
-
-    epgsql_pool_settings:set(connection_timeout, 5000),
-    ?assertEqual(5000, epgsql_pool_settings:get(connection_timeout)),
-
-    epgsql_pool_settings:set(max_reconnect_timeout, 4500),
-    ?assertEqual(4500, epgsql_pool_settings:get(max_reconnect_timeout)),
-
-    ?assertThrow({settings_not_found, some_key},
-                 epgsql_pool_settings:get(some_key)),
-
-    epgsql_pool_settings:set(some_key, 42),
-    ?assertEqual(42, epgsql_pool_settings:get(some_key)),
-
-    epgsql_pool_settings ! stop,
-    ok.
-
-
-connection_params_test() ->
-    epgsql_pool_settings:start_link(),
-
-    ?assertEqual({error, not_found}, epgsql_pool_settings:get_connection_params(some_pool)),
-
-    Params1 = #epgsql_connection_params{host = "localhost", port = 5432,
-                                        username="user", password="123",
-                                        database="db"},
-    epgsql_pool_settings:set_connection_params(pool_1, Params1),
-
-    Params2 = #epgsql_connection_params{host = "some.host", port = 5432,
-                                        username="someuser", password="123",
-                                        database="somedb"},
-    epgsql_pool_settings:set_connection_params(pool_2, Params2),
-
-    ?assertEqual({ok, Params1}, epgsql_pool_settings:get_connection_params(pool_1)),
-    ?assertEqual({ok, Params2}, epgsql_pool_settings:get_connection_params(pool_2)),
-
-    epgsql_pool_settings ! stop,
-    ok.

+ 1 - 2
test/epgsql_pool_tests.erl

@@ -5,7 +5,7 @@
 
 
 get_set_settings_test() ->
-    epgsql_pool_settings:start_link(),
+     application:ensure_all_started(epgsql_pool),
 
     ?assertEqual(#{connection_timeout => 10000,
                    keep_alive_timeout => 60000,
@@ -33,5 +33,4 @@ get_set_settings_test() ->
                    query_timeout => 555},
                  epgsql_pool:get_settings()),
 
-    epgsql_pool_settings ! stop,
     ok.