From f394c2552e780980f25bf7ca9afe197c57566d15 Mon Sep 17 00:00:00 2001 From: Lukasz Samson Date: Sun, 19 Jul 2026 09:25:45 +0200 Subject: [PATCH] Ignore stale ownership deadline timeouts --- integration_test/ownership/owner_test.exs | 17 +++++++++++++++++ lib/db_connection/ownership/proxy.ex | 6 ++++++ 2 files changed, 23 insertions(+) diff --git a/integration_test/ownership/owner_test.exs b/integration_test/ownership/owner_test.exs index ecce2dc4..69bc0d6f 100644 --- a/integration_test/ownership/owner_test.exs +++ b/integration_test/ownership/owner_test.exs @@ -143,4 +143,21 @@ defmodule OwnerTest do {:connect, _} ] = A.record(agent) end + + test "ignores a late deadline timer for a previous holder" do + stack = [{:ok, :state}] ++ List.duplicate({:idle, :state}, 2) + {:ok, agent} = A.start_link(stack) + + opts = [agent: agent, ownership_mode: :manual] + {:ok, pool} = P.start_link(opts) + + :ok = Ownership.ownership_checkout(pool, []) + {:owner, _ref, proxy} = Map.fetch!(:sys.get_state(pool).checkouts, self()) + monitor_ref = Process.monitor(proxy) + + send(proxy, {:timeout, make_ref(), {make_ref(), make_ref(), self(), 15_000}}) + + assert %{source: {:proxy, ^proxy}} = GenServer.call(proxy, :get_connection_metrics) + refute_receive {:DOWN, ^monitor_ref, :process, ^proxy, _reason} + end end diff --git a/lib/db_connection/ownership/proxy.ex b/lib/db_connection/ownership/proxy.ex index 41ac7f3d..dc9002f1 100644 --- a/lib/db_connection/ownership/proxy.ex +++ b/lib/db_connection/ownership/proxy.ex @@ -74,6 +74,12 @@ defmodule DBConnection.Ownership.Proxy do end end + # Deadline timers are cancelled asynchronously, so their messages may arrive + # after the holder has been transferred or replaced. + def handle_info({:timeout, _deadline, {_ref, _holder, _pid, _len}}, state) do + {:noreply, state} + end + def handle_info( {:timeout, timer, {__MODULE__, pid, timeout}}, %{ownership_timer: timer} = state