diff options
author | Paweł Chmielowski <pawel@process-one.net> | 2022-07-15 13:51:30 +0200 |
---|---|---|
committer | Paweł Chmielowski <pawel@process-one.net> | 2022-07-15 13:51:30 +0200 |
commit | 43f36205bd9a90a9f73f84f431029a57063d7255 (patch) | |
tree | 898847cddcc917ae1c842b58e7ba728258234b5b /src | |
parent | Don'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.
Diffstat (limited to 'src')
-rw-r--r-- | src/ejabberd_sql.erl | 21 |
1 files changed, 13 insertions, 8 deletions
diff --git a/src/ejabberd_sql.erl b/src/ejabberd_sql.erl index d0f7c658..6a11d034 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), |