Skip to content

Instantly share code, notes, and snippets.

@brettinternet
Created December 7, 2023 23:13
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save brettinternet/b2570e6a19c8f28996d1fd29b60a98e3 to your computer and use it in GitHub Desktop.
Save brettinternet/b2570e6a19c8f28996d1fd29b60a98e3 to your computer and use it in GitHub Desktop.
defmodule MyApp.RepoConnectionReaper do
@moduledoc """
Disconnect all connections after a X minutes to reset cache build-up and leaky memory on long-lived connections
Especially useful for dynamic queries which contribute to this build-up.
Alternatively, use this Repo option e.g. `Repo.all(query, prepare: :unnamed)` to avoid using named prepared statements
on queries that are dynamic enough to not cache the prepared statement on the connection.
See also
- https://github.com/elixir-ecto/db_connection/issues/99
- https://hexdocs.pm/db_connection/DBConnection.html#disconnect_all/3
"""
#
use GenServer
alias MyApp.Repo
@reap_interval_mins 30
def start_link(_) do
GenServer.start_link(__MODULE__, %{}, name: __MODULE__)
end
def init(state) do
:timer.send_interval(:timer.minutes(@reap_interval_mins), self(), :reap)
{:ok, state}
end
def handle_info(:reap, state) do
%{pid: pid, opts: opts} = Ecto.Adapter.lookup_meta(Repo)
DBConnection.disconnect_all(pid, :timer.minutes(10), opts)
{:noreply, state}
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment