2012-01-25 11:02:16 +01:00
|
|
|
%%%----------------------------------------------------------------------
|
|
|
|
%%% File : ejabberd_riak_sup.erl
|
|
|
|
%%% Author : Alexey Shchepin <alexey@process-one.net>
|
|
|
|
%%% Purpose : Riak connections supervisor
|
|
|
|
%%% Created : 29 Dec 2011 by Alexey Shchepin <alexey@process-one.net>
|
|
|
|
%%%
|
|
|
|
%%%
|
2017-01-02 21:41:53 +01:00
|
|
|
%%% ejabberd, Copyright (C) 2002-2017 ProcessOne
|
2012-01-25 11:02:16 +01:00
|
|
|
%%%
|
|
|
|
%%% This program is free software; you can redistribute it and/or
|
|
|
|
%%% modify it under the terms of the GNU General Public License as
|
|
|
|
%%% published by the Free Software Foundation; either version 2 of the
|
|
|
|
%%% License, or (at your option) any later version.
|
|
|
|
%%%
|
|
|
|
%%% This program is distributed in the hope that it will be useful,
|
|
|
|
%%% but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
%%% General Public License for more details.
|
|
|
|
%%%
|
2015-02-25 15:19:33 +01:00
|
|
|
%%% You should have received a copy of the GNU General Public License along
|
|
|
|
%%% with this program; if not, write to the Free Software Foundation, Inc.,
|
|
|
|
%%% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
2012-01-25 11:02:16 +01:00
|
|
|
%%%
|
|
|
|
%%%----------------------------------------------------------------------
|
|
|
|
|
|
|
|
-module(ejabberd_riak_sup).
|
2015-06-01 14:38:27 +02:00
|
|
|
|
2017-02-24 10:05:47 +01:00
|
|
|
-behaviour(supervisor).
|
2015-06-01 14:38:27 +02:00
|
|
|
-behaviour(ejabberd_config).
|
2012-01-25 11:02:16 +01:00
|
|
|
-author('alexey@process-one.net').
|
|
|
|
|
2017-02-24 10:05:47 +01:00
|
|
|
-export([start_link/0, init/1, get_pids/0,
|
2017-04-23 10:54:56 +02:00
|
|
|
transform_options/1, get_random_pid/0,
|
2017-02-24 10:05:47 +01:00
|
|
|
host_up/1, config_reloaded/0, opt_type/1]).
|
2012-01-25 11:02:16 +01:00
|
|
|
|
|
|
|
-include("ejabberd.hrl").
|
2014-07-09 14:40:18 +02:00
|
|
|
-include("logger.hrl").
|
2012-01-25 11:02:16 +01:00
|
|
|
|
|
|
|
-define(DEFAULT_POOL_SIZE, 10).
|
|
|
|
-define(DEFAULT_RIAK_START_INTERVAL, 30). % 30 seconds
|
2014-07-09 14:40:18 +02:00
|
|
|
-define(DEFAULT_RIAK_HOST, "127.0.0.1").
|
|
|
|
-define(DEFAULT_RIAK_PORT, 8087).
|
2012-01-25 11:02:16 +01:00
|
|
|
|
|
|
|
% time to wait for the supervisor to start its child before returning
|
|
|
|
% a timeout error to the request
|
|
|
|
-define(CONNECT_TIMEOUT, 500). % milliseconds
|
|
|
|
|
2017-02-24 10:05:47 +01:00
|
|
|
host_up(Host) ->
|
|
|
|
case is_riak_configured(Host) of
|
2017-02-23 08:12:19 +01:00
|
|
|
true ->
|
|
|
|
ejabberd:start_app(riakc),
|
2017-02-24 10:05:47 +01:00
|
|
|
lists:foreach(
|
|
|
|
fun(Spec) ->
|
|
|
|
supervisor:start_child(?MODULE, Spec)
|
|
|
|
end, get_specs());
|
2017-02-23 08:12:19 +01:00
|
|
|
false ->
|
2017-02-24 10:05:47 +01:00
|
|
|
ok
|
2017-02-23 08:12:19 +01:00
|
|
|
end.
|
|
|
|
|
2017-02-24 10:05:47 +01:00
|
|
|
config_reloaded() ->
|
|
|
|
case is_riak_configured() of
|
2014-07-09 14:40:18 +02:00
|
|
|
true ->
|
|
|
|
ejabberd:start_app(riakc),
|
2017-02-24 10:05:47 +01:00
|
|
|
lists:foreach(
|
|
|
|
fun(Spec) ->
|
|
|
|
supervisor:start_child(?MODULE, Spec)
|
|
|
|
end, get_specs());
|
2014-07-09 14:40:18 +02:00
|
|
|
false ->
|
2017-02-24 10:05:47 +01:00
|
|
|
lists:foreach(
|
|
|
|
fun({Id, _, _, _}) ->
|
|
|
|
supervisor:terminate_child(?MODULE, Id),
|
|
|
|
supervisor:delete_child(?MODULE, Id)
|
|
|
|
end, supervisor:which_children(?MODULE))
|
2012-11-06 16:58:08 +01:00
|
|
|
end.
|
|
|
|
|
2017-02-24 10:05:47 +01:00
|
|
|
is_riak_configured() ->
|
|
|
|
lists:any(fun is_riak_configured/1, ?MYHOSTS).
|
|
|
|
|
2014-07-09 14:40:18 +02:00
|
|
|
is_riak_configured(Host) ->
|
2017-04-15 09:02:32 +02:00
|
|
|
ServerConfigured = ejabberd_config:has_option({riak_server, Host}),
|
|
|
|
PortConfigured = ejabberd_config:has_option({riak_port, Host}),
|
|
|
|
StartIntervalConfigured = ejabberd_config:has_option({riak_start_interval, Host}),
|
|
|
|
PoolConfigured = ejabberd_config:has_option({riak_pool_size, Host}),
|
|
|
|
CacertConfigured = ejabberd_config:has_option({riak_cacertfile, Host}),
|
|
|
|
UserConfigured = ejabberd_config:has_option({riak_username, Host}),
|
|
|
|
PassConfigured = ejabberd_config:has_option({riak_password, Host}),
|
2014-07-15 18:26:32 +02:00
|
|
|
AuthConfigured = lists:member(
|
|
|
|
ejabberd_auth_riak,
|
|
|
|
ejabberd_auth:auth_modules(Host)),
|
2017-04-29 10:39:40 +02:00
|
|
|
SMConfigured = ejabberd_config:get_option({sm_db_type, Host}) == riak,
|
|
|
|
RouterConfigured = ejabberd_config:get_option({router_db_type, Host}) == riak,
|
2017-04-15 09:02:32 +02:00
|
|
|
ServerConfigured or PortConfigured or StartIntervalConfigured
|
|
|
|
or PoolConfigured or CacertConfigured
|
|
|
|
or UserConfigured or PassConfigured
|
|
|
|
or SMConfigured or RouterConfigured
|
2017-05-21 10:33:16 +02:00
|
|
|
or AuthConfigured.
|
2014-07-09 14:40:18 +02:00
|
|
|
|
2012-01-25 11:02:16 +01:00
|
|
|
start_link() ->
|
|
|
|
supervisor:start_link({local, ?MODULE}, ?MODULE, []).
|
|
|
|
|
|
|
|
init([]) ->
|
2017-02-24 10:05:47 +01:00
|
|
|
ejabberd_hooks:add(config_reloaded, ?MODULE, config_reloaded, 20),
|
|
|
|
ejabberd_hooks:add(host_up, ?MODULE, host_up, 20),
|
|
|
|
Specs = case is_riak_configured() of
|
|
|
|
true ->
|
|
|
|
ejabberd:start_app(riakc),
|
|
|
|
get_specs();
|
|
|
|
false ->
|
|
|
|
[]
|
|
|
|
end,
|
|
|
|
{ok, {{one_for_one, 500, 1}, Specs}}.
|
|
|
|
|
|
|
|
-spec get_specs() -> [supervisor:child_spec()].
|
|
|
|
get_specs() ->
|
2014-07-09 14:40:18 +02:00
|
|
|
PoolSize = get_pool_size(),
|
|
|
|
StartInterval = get_start_interval(),
|
|
|
|
Server = get_riak_server(),
|
|
|
|
Port = get_riak_port(),
|
2016-03-18 17:41:14 +01:00
|
|
|
CACertFile = get_riak_cacertfile(),
|
|
|
|
Username = get_riak_username(),
|
|
|
|
Password = get_riak_password(),
|
|
|
|
Options = lists:filter(
|
|
|
|
fun(X) -> X /= nil end,
|
|
|
|
[auto_reconnect,
|
2016-03-22 17:32:30 +01:00
|
|
|
{keepalive, true},
|
2016-03-18 17:41:14 +01:00
|
|
|
if CACertFile /= nil -> {cacertfile ,CACertFile};
|
|
|
|
true -> nil
|
|
|
|
end,
|
|
|
|
if (Username /= nil) and (Password /= nil) ->
|
|
|
|
{credentials, Username, Password};
|
|
|
|
true -> nil
|
2017-02-24 10:05:47 +01:00
|
|
|
end]),
|
|
|
|
lists:map(
|
|
|
|
fun(I) ->
|
|
|
|
{ejabberd_riak:get_proc(I),
|
|
|
|
{ejabberd_riak, start_link,
|
|
|
|
[I, Server, Port, StartInterval*1000, Options]},
|
|
|
|
transient, 2000, worker, [?MODULE]}
|
|
|
|
end, lists:seq(1, PoolSize)).
|
2012-01-25 11:02:16 +01:00
|
|
|
|
2014-07-09 14:40:18 +02:00
|
|
|
get_start_interval() ->
|
2017-04-29 10:39:40 +02:00
|
|
|
ejabberd_config:get_option(riak_start_interval, ?DEFAULT_RIAK_START_INTERVAL).
|
2014-07-09 14:40:18 +02:00
|
|
|
|
|
|
|
get_pool_size() ->
|
2017-04-29 10:39:40 +02:00
|
|
|
ejabberd_config:get_option(riak_pool_size, ?DEFAULT_POOL_SIZE).
|
2014-07-09 14:40:18 +02:00
|
|
|
|
|
|
|
get_riak_server() ->
|
2017-04-29 10:39:40 +02:00
|
|
|
ejabberd_config:get_option(riak_server, ?DEFAULT_RIAK_HOST).
|
2014-07-09 14:40:18 +02:00
|
|
|
|
2016-03-18 17:41:14 +01:00
|
|
|
get_riak_cacertfile() ->
|
2017-04-29 10:39:40 +02:00
|
|
|
ejabberd_config:get_option(riak_cacertfile, nil).
|
2016-03-18 17:41:14 +01:00
|
|
|
|
|
|
|
get_riak_username() ->
|
2017-04-29 10:39:40 +02:00
|
|
|
ejabberd_config:get_option(riak_username, nil).
|
2016-03-18 17:41:14 +01:00
|
|
|
|
|
|
|
get_riak_password() ->
|
2017-04-29 10:39:40 +02:00
|
|
|
ejabberd_config:get_option(riak_password, nil).
|
2016-03-18 17:41:14 +01:00
|
|
|
|
2014-07-09 14:40:18 +02:00
|
|
|
get_riak_port() ->
|
2017-04-29 10:39:40 +02:00
|
|
|
ejabberd_config:get_option(riak_port, ?DEFAULT_RIAK_PORT).
|
2014-07-09 14:40:18 +02:00
|
|
|
|
2012-01-25 11:02:16 +01:00
|
|
|
get_pids() ->
|
2014-07-09 14:40:18 +02:00
|
|
|
[ejabberd_riak:get_proc(I) || I <- lists:seq(1, get_pool_size())].
|
2012-01-25 11:02:16 +01:00
|
|
|
|
|
|
|
get_random_pid() ->
|
2017-04-23 10:54:56 +02:00
|
|
|
I = randoms:round_robin(get_pool_size()) + 1,
|
2014-07-09 14:40:18 +02:00
|
|
|
ejabberd_riak:get_proc(I).
|
|
|
|
|
|
|
|
transform_options(Opts) ->
|
|
|
|
lists:foldl(fun transform_options/2, [], Opts).
|
|
|
|
|
|
|
|
transform_options({riak_server, {S, P}}, Opts) ->
|
|
|
|
[{riak_server, S}, {riak_port, P}|Opts];
|
|
|
|
transform_options(Opt, Opts) ->
|
|
|
|
[Opt|Opts].
|
2015-06-01 14:38:27 +02:00
|
|
|
|
2017-05-08 11:59:28 +02:00
|
|
|
-spec opt_type(riak_pool_size) -> fun((pos_integer()) -> pos_integer());
|
|
|
|
(riak_port) -> fun((0..65535) -> 0..65535);
|
|
|
|
(riak_server) -> fun((binary()) -> binary());
|
|
|
|
(riak_start_interval) -> fun((pos_integer()) -> pos_integer());
|
|
|
|
(riak_cacertfile) -> fun((binary()) -> binary());
|
|
|
|
(riak_username) -> fun((binary()) -> binary());
|
|
|
|
(riak_password) -> fun((binary()) -> binary());
|
|
|
|
(atom()) -> [atom()].
|
2015-06-01 14:38:27 +02:00
|
|
|
opt_type(riak_pool_size) ->
|
|
|
|
fun (N) when is_integer(N), N >= 1 -> N end;
|
2017-04-29 10:39:40 +02:00
|
|
|
opt_type(riak_port) ->
|
|
|
|
fun(P) when is_integer(P), P > 0, P < 65536 -> P end;
|
|
|
|
opt_type(riak_server) ->
|
|
|
|
fun(S) -> binary_to_list(iolist_to_binary(S)) end;
|
2015-06-01 14:38:27 +02:00
|
|
|
opt_type(riak_start_interval) ->
|
|
|
|
fun (N) when is_integer(N), N >= 1 -> N end;
|
2017-04-29 10:39:40 +02:00
|
|
|
opt_type(riak_cacertfile) ->
|
|
|
|
fun(S) -> binary_to_list(iolist_to_binary(S)) end;
|
|
|
|
opt_type(riak_username) ->
|
|
|
|
fun(S) -> binary_to_list(iolist_to_binary(S)) end;
|
|
|
|
opt_type(riak_password) ->
|
|
|
|
fun(S) -> binary_to_list(iolist_to_binary(S)) end;
|
2015-06-01 14:38:27 +02:00
|
|
|
opt_type(_) ->
|
2017-04-28 12:23:32 +02:00
|
|
|
[riak_pool_size, riak_port, riak_server,
|
2016-03-18 17:41:14 +01:00
|
|
|
riak_start_interval, riak_cacertfile, riak_username, riak_password].
|