aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaweł Chmielowski <pawel@process-one.net>2022-07-15 13:51:30 +0200
committerPaweł Chmielowski <pawel@process-one.net>2022-07-15 13:51:30 +0200
commit43f36205bd9a90a9f73f84f431029a57063d7255 (patch)
tree898847cddcc917ae1c842b58e7ba728258234b5b
parentDon't set affiliation to 'none' if it's already 'none' in mod_muc_room:proces... (diff)
React to sql driver process exit earlier
If there are queued request when connection closes we may try to process those requests (by trying to send them to already terminated db process, and waiting until we hit timeout) before we see that driver is not longer alive. This change adds check for driver exit before we process next queued sql request, and immediately switch to connection state if we have one.
-rw-r--r--src/ejabberd_sql.erl21
1 files changed, 13 insertions, 8 deletions
diff --git a/src/ejabberd_sql.erl b/src/ejabberd_sql.erl
index d0f7c658f..6a11d0346 100644
--- a/src/ejabberd_sql.erl
+++ b/src/ejabberd_sql.erl
@@ -483,9 +483,16 @@ run_sql_cmd(Command, From, State, Timestamp) ->
State1 = report_overload(State),
{next_state, session_established, State1};
false ->
- put(?NESTING_KEY, ?TOP_LEVEL_TXN),
- put(?STATE_KEY, State),
- abort_on_driver_error(outer_op(Command), From, Timestamp)
+ receive
+ {'EXIT', _Pid, Reason} ->
+ PR = p1_queue:in({sql_cmd, Command, From, Timestamp},
+ State#state.pending_requests),
+ handle_reconnect(Reason, State#state{pending_requests = PR})
+ after 0 ->
+ put(?NESTING_KEY, ?TOP_LEVEL_TXN),
+ put(?STATE_KEY, State),
+ abort_on_driver_error(outer_op(Command), From, Timestamp)
+ end
end.
%% @doc Only called by handle_call, only handles top level operations.
@@ -670,11 +677,10 @@ sql_query_internal(Query) ->
pgsql_to_odbc(pgsql:squery(State#state.db_ref, Query,
QueryTimeout - 1000));
mysql ->
- R = mysql_to_odbc(p1_mysql_conn:squery(State#state.db_ref,
+ mysql_to_odbc(p1_mysql_conn:squery(State#state.db_ref,
[Query], self(),
- [{timeout, QueryTimeout - 1000},
- {result_type, binary}])),
- R;
+ [{QueryTimeout - 1000},
+ {result_type, binary}]));
sqlite ->
Host = State#state.host,
sqlite_to_odbc(Host, sqlite3:sql_exec(sqlite_db(Host), Query))
@@ -854,7 +860,6 @@ sql_rollback() ->
[{mssql, [<<"rollback transaction;">>]},
{any, [<<"rollback;">>]}]).
-
%% Generate the OTP callback return tuple depending on the driver result.
abort_on_driver_error({error, <<"query timed out">>} = Reply, From, Timestamp) ->
reply(From, Reply, Timestamp),