Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 6 additions & 4 deletions lib/absinthe/subscription.ex
Original file line number Diff line number Diff line change
Expand Up @@ -179,11 +179,13 @@ defmodule Absinthe.Subscription do
def unsubscribe(pubsub, doc_id) do
registry = pubsub |> registry_name

for field_key <- pdict_fields(doc_id) do
Registry.unregister_match(registry, field_key, doc_id)
end
if Process.whereis(registry) do
for field_key <- pdict_fields(doc_id) do
Registry.unregister_match(registry, field_key, doc_id)
end

Registry.unregister(registry, doc_id)
Registry.unregister(registry, doc_id)
end

pdict_delete_fields(doc_id)
:ok
Expand Down
23 changes: 23 additions & 0 deletions test/absinthe/execution/subscription_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -326,6 +326,29 @@ defmodule Absinthe.Execution.SubscriptionTest do
refute_receive({:broadcast, _})
end

test "unsubscribe does not raise when registry is down" do
# Use a dedicated pubsub/registry to avoid affecting other tests.
# This simulates the scenario where Absinthe.Subscription is terminated
# before the Endpoint during graceful shutdown (OTP terminates children
# in reverse start order), causing active SSE connections to call
# unsubscribe/2 against a registry that no longer exists.
pubsub = ShutdownTestPubSub
registry_name = Absinthe.Subscription.registry_name(pubsub)
Registry.start_link(keys: :duplicate, name: registry_name, partitions: 1)

doc_id = "test_doc_id"
field_key = "test_field_key"

{:ok, _} = Registry.register(registry_name, field_key, doc_id)
{:ok, _} = Registry.register(registry_name, doc_id, %{})
Process.put({Absinthe.Subscription, doc_id}, [field_key])

Process.flag(:trap_exit, true)
GenServer.stop(registry_name)

assert :ok = Absinthe.Subscription.unsubscribe(pubsub, doc_id)
end

test "can unsubscribe from duplicate subscriptions individually" do
client_id = "abc"

Expand Down
Loading