Skip to content

Commit 9512c28

Browse files
authored
Add label (repo name) to ownership errors (#332)
Include pool name in ownership errors via process labels When a `label` option (e.g., `label: MyApp.Repo`) is passed to DBConnection, the Ownership Manager stores it as a process label. When set, this is added to "cannot find ownership process" errors. Before: (DBConnection.OwnershipError) cannot find ownership process for #PID<0.502.0> using mode :manual. After: (DBConnection.OwnershipError) cannot find ownership process for #PID<0.502.0> (MyApp.Repo) using mode :manual.
1 parent 0ac055a commit 9512c28

3 files changed

Lines changed: 55 additions & 2 deletions

File tree

integration_test/ownership/manager_test.exs

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -681,6 +681,35 @@ defmodule ManagerTest do
681681
assert log =~ "** (RuntimeError) oops"
682682
end
683683

684+
test "includes label in ownership error when label is provided" do
685+
if function_exported?(:proc_lib, :get_label, 1) do
686+
{:ok, pool, opts} = start_pool(label: TestRepo)
687+
688+
error =
689+
assert_raise DBConnection.OwnershipError, fn ->
690+
P.run(pool, fn _ -> :ok end, opts)
691+
end
692+
693+
assert error.message =~ "cannot find ownership process"
694+
assert error.message =~ "using mode :manual"
695+
696+
assert error.message =~ "(TestRepo)"
697+
end
698+
end
699+
700+
test "doesn't require a label to produce an ownership error" do
701+
{:ok, pool, opts} = start_pool()
702+
703+
# Try to use the pool without checking out - should raise OwnershipError
704+
error =
705+
assert_raise DBConnection.OwnershipError, fn ->
706+
P.run(pool, fn _ -> :ok end, opts)
707+
end
708+
709+
assert error.message =~ "cannot find ownership process"
710+
assert error.message =~ "using mode :manual"
711+
end
712+
684713
defp start_pool(opts \\ []) do
685714
stack = [{:ok, :state}] ++ List.duplicate({:idle, :state}, 10)
686715
{:ok, agent} = A.start_link(stack)

lib/db_connection/ownership/manager.ex

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,10 @@ defmodule DBConnection.Ownership.Manager do
9898
mode = Keyword.get(pool_opts, :ownership_mode, :auto)
9999
checkout_opts = Keyword.take(pool_opts, [:ownership_timeout, :queue_target, :queue_interval])
100100

101+
if label = pool_opts[:label] do
102+
Util.set_label({__MODULE__, label})
103+
end
104+
101105
{:ok,
102106
%{
103107
pool: pool,
@@ -406,9 +410,14 @@ defmodule DBConnection.Ownership.Manager do
406410
end
407411

408412
defp not_found({pid, _} = from, mode) do
413+
label = Util.pool_label(self())
414+
label_info = if label, do: "(#{inspect(label)}) ", else: ""
415+
409416
msg = """
410417
cannot find ownership process for #{Util.inspect_pid(pid)}
411-
using mode #{inspect(mode)}.
418+
#{label_info}using mode #{inspect(mode)}.
419+
(Note that a connection's mode reverts to :manual if its owner
420+
terminates.)
412421
413422
When using ownership, you must manage connections in one
414423
of the four ways:

lib/db_connection/util.ex

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,12 +32,27 @@ defmodule DBConnection.Util do
3232
"""
3333
def set_label(label) do
3434
if function_exported?(Process, :set_label, 1) do
35-
Process.set_label(label)
35+
apply(Process, :set_label, [label])
3636
else
3737
:ok
3838
end
3939
end
4040

41+
@doc """
42+
Get the pool label from a pid's process label.
43+
44+
Returns the label if found, or `nil` otherwise.
45+
Process labels set as `{module, label}` tuples have the label extracted.
46+
"""
47+
def pool_label(pid) when is_pid(pid) do
48+
case get_label(pid) do
49+
{module, label} when is_atom(module) and module != nil and label != nil -> label
50+
_ -> nil
51+
end
52+
end
53+
54+
def pool_label(_other), do: nil
55+
4156
# Get a process label if `:proc_lib.get_label/1` is available.
4257
defp get_label(pid) do
4358
if function_exported?(:proc_lib, :get_label, 1) do

0 commit comments

Comments
 (0)