From c076e31f3b81dabdd307a1632df9fda68d6d5334 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Jan=20Niemier?= Date: Mon, 25 Nov 2024 16:46:42 +0100 Subject: [PATCH] fix: cleanly shutdown `DbHandler` on failure --- lib/supavisor/client_handler.ex | 17 +++++++++++++++-- lib/supavisor/db_handler.ex | 4 ++-- 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/lib/supavisor/client_handler.ex b/lib/supavisor/client_handler.ex index b1e06c61..e41f7811 100644 --- a/lib/supavisor/client_handler.ex +++ b/lib/supavisor/client_handler.ex @@ -470,7 +470,20 @@ defmodule Supavisor.ClientHandler do } {:ok, db_pid} = DbHandler.start_link(args) - db_sock = :gen_statem.call(db_pid, {:checkout, data.sock, self()}) + + db_sock = + try do + DbHandler.checkout(db_pid, data.sock) + rescue + err -> + Logger.error( + "ClientHandler: Error while connecting to the DB - #{Exception.message(err)}" + ) + + _ = DbHandler.stop(db_pid) + reraise err, __STACKTRACE__ + end + {:keep_state, %{data | db_pid: {nil, db_pid, db_sock}, mode: :proxy}} end @@ -852,7 +865,7 @@ defmodule Supavisor.ClientHandler do start = System.monotonic_time(:microsecond) db_pid = :poolboy.checkout(data.pool, true, data.timeout) Process.link(db_pid) - db_sock = DbHandler.checkout(db_pid, data.sock, self()) + db_sock = DbHandler.checkout(db_pid, data.sock) same_box = if node(db_pid) == node(), do: :local, else: :remote Telem.pool_checkout_time(System.monotonic_time(:microsecond) - start, data.id, same_box) {data.pool, db_pid, db_sock} diff --git a/lib/supavisor/db_handler.ex b/lib/supavisor/db_handler.ex index 1d7ff475..f7f0abbb 100644 --- a/lib/supavisor/db_handler.ex +++ b/lib/supavisor/db_handler.ex @@ -28,8 +28,8 @@ defmodule Supavisor.DbHandler do def start_link(config), do: :gen_statem.start_link(__MODULE__, config, hibernate_after: 5_000) - def checkout(pid, sock, caller, timeout \\ 15_000), - do: :gen_statem.call(pid, {:checkout, sock, caller}, timeout) + def checkout(pid, sock, timeout \\ 15_000), + do: :gen_statem.call(pid, {:checkout, sock, self()}, timeout) @spec checkin(pid()) :: :ok def checkin(pid), do: :gen_statem.cast(pid, :checkin)