diff --git a/lib/event_store/config.ex b/lib/event_store/config.ex index f32ec2a..b8b28c6 100644 --- a/lib/event_store/config.ex +++ b/lib/event_store/config.ex @@ -115,6 +115,7 @@ defmodule EventStore.Config do :backoff_max, :backoff_min, :backoff_type, + :checkout_retries, :configure, :connect_timeout, :connection_listeners, @@ -124,6 +125,8 @@ defmodule EventStore.Config do :handshake_timeout, :hostname, :idle_interval, + :idle_limit, + :max_lifetime, :max_restarts, :max_seconds, :parameters, @@ -148,8 +151,12 @@ defmodule EventStore.Config do :username ] + # Only the main pool may recycle connections, every other connection holds + # state tied to its lifetime (advisory locks, LISTEN registrations). def default_postgrex_opts(config) do - Keyword.take(config, @postgrex_connection_opts) + config + |> Keyword.take(@postgrex_connection_opts) + |> Keyword.delete(:max_lifetime) end def postgrex_opts(config, name) do diff --git a/mix.exs b/mix.exs index 2eec4bf..d390d60 100644 --- a/mix.exs +++ b/mix.exs @@ -38,6 +38,7 @@ defmodule EventStore.Mixfile do defp deps do [ + {:db_connection, "~> 2.10"}, {:gen_stage, "~> 1.2"}, {:postgrex, "~> 0.22"}, {:telemetry, "~> 1.0"}, diff --git a/test/config_test.exs b/test/config_test.exs index 5702588..3aa8322 100644 --- a/test/config_test.exs +++ b/test/config_test.exs @@ -190,6 +190,40 @@ defmodule EventStore.ConfigTest do ] end + describe "connection pool options" do + setup do + config = + Config.parse( + url: "postgres://username:password@localhost/database", + checkout_retries: 5, + idle_limit: 2, + max_lifetime: 480_000..540_000 + ) + + [config: config] + end + + test "main pool accepts every option", %{config: config} do + opts = Config.postgrex_opts(config, :name) + + assert opts[:checkout_retries] == 5 + assert opts[:idle_limit] == 2 + assert opts[:max_lifetime] == 480_000..540_000 + end + + test "connections other than the main pool are never recycled", %{config: config} do + for opts <- [ + Config.default_postgrex_opts(config), + Config.advisory_locks_postgrex_opts(config), + Config.postgrex_notifications_opts(config, :name) + ] do + assert opts[:checkout_retries] == 5 + assert opts[:idle_limit] == 2 + refute Keyword.has_key?(opts, :max_lifetime) + end + end + end + test "parse url with query parameters" do config = [ url: "postgres://username:password@localhost/database?ssl=true&pool_size=5&timeout=120000"