Skip to content

Commit 2b5d5e7

Browse files
committed
Add function for checking sql workers state
1 parent a736a8f commit 2b5d5e7

1 file changed

Lines changed: 29 additions & 1 deletion

File tree

src/ejabberd_sql.erl

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,8 @@
6262
keep_alive/2,
6363
to_list/2,
6464
to_array/2,
65-
parse_mysql_version/2]).
65+
parse_mysql_version/2,
66+
get_workers_status/1]).
6667

6768
%% gen_fsm callbacks
6869
-export([init/1, handle_event/3, handle_sync_event/4,
@@ -106,6 +107,7 @@
106107
timeout :: pos_integer()}).
107108

108109
-define(STATE_KEY, ejabberd_sql_state).
110+
-define(STATUS_KEY, ejabberd_sql_status).
109111
-define(NESTING_KEY, ejabberd_sql_nesting_level).
110112
-define(TOP_LEVEL_TXN, 0).
111113
-define(MAX_TRANSACTION_RESTARTS, 10).
@@ -390,6 +392,29 @@ get_worker(Host) ->
390392
get_worker_name(Host, I) ->
391393
<<"ejabberd_sql_", Host/binary, $_, (integer_to_binary(I))/binary>>.
392394

395+
-spec get_workers_status(binary()) -> #{connected => pos_integer(), disconnected => pos_integer(), overloaded => pos_integer}.
396+
get_workers_status(Host) ->
397+
PoolSize = ejabberd_option:sql_pool_size(Host),
398+
lists:foldl(
399+
fun(I, #{connected := C, disconnected := D, overloaded := O} = Acc) ->
400+
maybe
401+
Pid ?= whereis(binary_to_atom(get_worker_name(Host, I), utf8)),
402+
true ?= is_pid(Pid),
403+
{dictionary, Dict} ?= process_info(Pid, dictionary),
404+
case lists:keyfind(?STATUS_KEY, 1, Dict) of
405+
{_, connected} -> Acc#{connected => C+1};
406+
{_, {overloaded, TS}} ->
407+
case current_time() - TS > timer:seconds(60) of
408+
true -> Acc#{connected => C+1};
409+
_ -> Acc#{overloaded => O+1}
410+
end;
411+
_ -> Acc#{disconnected => D+1}
412+
end
413+
else
414+
_ -> Acc#{disconnected => D+1}
415+
end
416+
end, #{connected => 0, disconnected => 0, overloaded => 0}, lists:seq(1, PoolSize)).
417+
393418
%%%----------------------------------------------------------------------
394419
%%% Callback functions from gen_fsm
395420
%%%----------------------------------------------------------------------
@@ -437,6 +462,7 @@ connecting(connect, #state{host = Host} = State) ->
437462
State1 = State#state{db_ref = Ref,
438463
pending_requests = PendingRequests},
439464
State2 = get_db_version(State1),
465+
put(?STATUS_KEY, connected),
440466
{next_state, session_established, State2#state{reconnect_count = 0}}
441467
catch _:Reason ->
442468
handle_reconnect(Reason, State)
@@ -548,6 +574,7 @@ handle_reconnect(Reason, #state{host = Host, reconnect_count = RC} = State) ->
548574
pgsql -> catch pgsql:terminate(State#state.db_ref);
549575
_ -> ok
550576
end,
577+
put(?STATUS_KEY, disconnected),
551578
p1_fsm:send_event_after(StartInterval, connect),
552579
{next_state, connecting, State#state{reconnect_count = RC + 1,
553580
timeout = query_timeout(Host)}}.
@@ -1039,6 +1066,7 @@ abort_on_driver_error(Reply, From, Timestamp) ->
10391066
-spec report_overload(state()) -> state().
10401067
report_overload(#state{overload_reported = PrevTime} = State) ->
10411068
CurrTime = current_time(),
1069+
put(?STATUS_KEY, {overloaded, CurrTime}),
10421070
case PrevTime == undefined orelse (CurrTime - PrevTime) > timer:seconds(30) of
10431071
true ->
10441072
?ERROR_MSG("SQL connection pool is overloaded, "

0 commit comments

Comments
 (0)