From 65b47ec19174d327c2e37b4dbe93e1152858f347 Mon Sep 17 00:00:00 2001 From: Steffen Beyer Date: Tue, 17 Mar 2026 18:49:50 +0100 Subject: [PATCH] fix: Subscription workers restart strategy, sandbox ownership race condition --- lib/parrhesia/api/stream/subscription.ex | 2 +- test/support/integration_case.ex | 31 ++++++++++++++++++++++-- test/support/runtime.ex | 1 + 3 files changed, 31 insertions(+), 3 deletions(-) diff --git a/lib/parrhesia/api/stream/subscription.ex b/lib/parrhesia/api/stream/subscription.ex index 80fb475..f66622b 100644 --- a/lib/parrhesia/api/stream/subscription.ex +++ b/lib/parrhesia/api/stream/subscription.ex @@ -1,7 +1,7 @@ defmodule Parrhesia.API.Stream.Subscription do @moduledoc false - use GenServer + use GenServer, restart: :temporary alias Parrhesia.Protocol.Filter alias Parrhesia.Subscriptions.Index diff --git a/test/support/integration_case.ex b/test/support/integration_case.ex index 5d41e96..5c91e3a 100644 --- a/test/support/integration_case.ex +++ b/test/support/integration_case.ex @@ -30,11 +30,38 @@ defmodule Parrhesia.IntegrationCase do :ok = Sandbox.checkout(Repo) :shared -> - :ok = Sandbox.checkout(Repo) - Sandbox.mode(Repo, {:shared, self()}) + # Delegate sandbox ownership to a dedicated process that outlives + # the test process. ExUnit terminates start_supervised! children + # (in reverse start order) before running on_exit callbacks. With + # the test process as sandbox owner, the connection dies the + # moment the test process exits — supervised children that make + # DB calls during their shutdown sequence would hit a dead + # connection. The separate owner stays alive through the entire + # supervised-child shutdown, and is only stopped in on_exit + # (which runs afterwards). + test_pid = self() + + owner = + spawn(fn -> + :ok = Sandbox.checkout(Repo) + send(test_pid, {:sandbox_ready, self()}) + + receive do + :stop -> :ok + end + end) + + receive do + {:sandbox_ready, ^owner} -> :ok + after + 5_000 -> raise "Sandbox owner checkout timed out" + end + + Sandbox.mode(Repo, {:shared, owner}) on_exit(fn -> Sandbox.mode(Repo, :manual) + send(owner, :stop) end) end diff --git a/test/support/runtime.ex b/test/support/runtime.ex index 4d71765..179aa7d 100644 --- a/test/support/runtime.ex +++ b/test/support/runtime.ex @@ -6,6 +6,7 @@ defmodule Parrhesia.TestSupport.Runtime do Parrhesia.Config, Parrhesia.Repo, Parrhesia.Subscriptions.Supervisor, + Parrhesia.API.Stream.Supervisor, Parrhesia.Web.Endpoint ]