From 1518b46fa5658e163351f312c501d8e7cb6a9b2f Mon Sep 17 00:00:00 2001 From: Victor Gaiva <13839490+VictorGaiva@users.noreply.github.com> Date: Wed, 13 Dec 2023 14:53:54 -0300 Subject: [PATCH 1/3] fix: Adds the option to periodically garbage collect the channel process --- lib/absinthe/phoenix/channel.ex | 19 ++++++++++++++++--- lib/absinthe/phoenix/socket.ex | 16 +++++++++++++++- 2 files changed, 31 insertions(+), 4 deletions(-) diff --git a/lib/absinthe/phoenix/channel.ex b/lib/absinthe/phoenix/channel.ex index 5e32a8b..3d10bb8 100644 --- a/lib/absinthe/phoenix/channel.ex +++ b/lib/absinthe/phoenix/channel.ex @@ -17,6 +17,7 @@ defmodule Absinthe.Phoenix.Channel do def join("__absinthe__:control", _, socket) do schema = socket.assigns[:__absinthe_schema__] pipeline = socket.assigns[:__absinthe_pipeline__] + gc_interval = socket.assigns[:__absinthe_gc_interval__] absinthe_config = Map.get(socket.assigns, :absinthe, %{}) @@ -32,7 +33,13 @@ defmodule Absinthe.Phoenix.Channel do |> Map.update(:schema, schema, & &1) absinthe_config = - Map.put(absinthe_config, :pipeline, pipeline || {__MODULE__, :default_pipeline}) + absinthe_config + |> Map.put(:pipeline, pipeline || {__MODULE__, :default_pipeline}) + |> Map.put(:gc_interval, gc_interval) + + unless gc_interval == nil do + Process.send_after(self(), :gc, gc_interval) + end socket = socket |> assign(:absinthe, absinthe_config) {:ok, socket} @@ -142,7 +149,13 @@ defmodule Absinthe.Phoenix.Channel do |> Absinthe.Pipeline.for_document(options) end - def handle_info(_, state) do - {:noreply, state} + def handle_info(:gc, socket) do + :erlang.garbage_collect() + Process.send_after(self(), :gc, socket.assigns.absinthe.gc_interval) + {:noreply, socket} + end + + def handle_info(_, socket) do + {:noreply, socket} end end diff --git a/lib/absinthe/phoenix/socket.ex b/lib/absinthe/phoenix/socket.ex index 2508f86..052ef03 100644 --- a/lib/absinthe/phoenix/socket.ex +++ b/lib/absinthe/phoenix/socket.ex @@ -25,6 +25,18 @@ defmodule Absinthe.Phoenix.Socket do ## Phoenix 1.2 If you're on Phoenix 1.2 see `put_schema/2`. + + ## Garbage Collection + + In some workloads, the Channel Process responsible for handling [subscriptions may accumulate + some gargage](https://elixirforum.com/t/why-does-garbage-collection-not-work-as-intended/50613/2), that is not being collected by the Erlang VM. A workaround for this is to instruct + the process to periodically tell the VM to collect its garbage. This can be done by setting the + `gc_interval`. + + use Absinthe.Phoenix.Socket, + schema: MyApp.Web.Schema, + gc_interval: 10_000 + """ defmacro __using__(opts) do @@ -37,6 +49,7 @@ defmodule Absinthe.Phoenix.Socket do schema = Keyword.get(opts, :schema) pipeline = Keyword.get(opts, :pipeline) + gc_interval = Keyword.get(opts, :gc_interval) quote do channel( @@ -44,7 +57,8 @@ defmodule Absinthe.Phoenix.Socket do Absinthe.Phoenix.Channel, assigns: %{ __absinthe_schema__: unquote(schema), - __absinthe_pipeline__: unquote(pipeline) + __absinthe_pipeline__: unquote(pipeline), + __absinthe_gc_interval: unquote(gc_interval) } ) end From 404bb2025b407bb2bda5d355167ebd2cc6b637a3 Mon Sep 17 00:00:00 2001 From: Victor Gaiva <13839490+VictorGaiva@users.noreply.github.com> Date: Thu, 14 Dec 2023 09:50:48 -0300 Subject: [PATCH 2/3] fix: Add GC to transport process --- lib/absinthe/phoenix/channel.ex | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/absinthe/phoenix/channel.ex b/lib/absinthe/phoenix/channel.ex index 3d10bb8..96c0d97 100644 --- a/lib/absinthe/phoenix/channel.ex +++ b/lib/absinthe/phoenix/channel.ex @@ -151,6 +151,7 @@ defmodule Absinthe.Phoenix.Channel do def handle_info(:gc, socket) do :erlang.garbage_collect() + :erlang.garbage_collect(socket.transport_pid) Process.send_after(self(), :gc, socket.assigns.absinthe.gc_interval) {:noreply, socket} end From cdf34983e429eeb5c1d5372a33cf683323fba24b Mon Sep 17 00:00:00 2001 From: Victor Gaiva <13839490+VictorGaiva@users.noreply.github.com> Date: Thu, 14 Dec 2023 12:39:35 -0300 Subject: [PATCH 3/3] fix: Fix assign key --- lib/absinthe/phoenix/socket.ex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/absinthe/phoenix/socket.ex b/lib/absinthe/phoenix/socket.ex index 052ef03..9f46655 100644 --- a/lib/absinthe/phoenix/socket.ex +++ b/lib/absinthe/phoenix/socket.ex @@ -58,7 +58,7 @@ defmodule Absinthe.Phoenix.Socket do assigns: %{ __absinthe_schema__: unquote(schema), __absinthe_pipeline__: unquote(pipeline), - __absinthe_gc_interval: unquote(gc_interval) + __absinthe_gc_interval__: unquote(gc_interval) } ) end