diff --git a/src/invidious/config.cr b/src/invidious/config.cr index 2319cca0..5304296f 100644 --- a/src/invidious/config.cr +++ b/src/invidious/config.cr @@ -164,7 +164,7 @@ class Config property idle_pool_size : Int32? = nil # Amount of seconds to wait for a client to be free from the pool before rasing an error - property pool_checkout_timeout : Int32 = 5 + property pool_checkout_timeout : Float64 = 5 # HTTP Proxy configuration property http_proxy : HTTPProxyConfig? = nil diff --git a/src/invidious/connection/pool.cr b/src/invidious/connection/pool.cr index 5dd169fd..e9b0ca18 100644 --- a/src/invidious/connection/pool.cr +++ b/src/invidious/connection/pool.cr @@ -3,31 +3,26 @@ module Invidious::ConnectionPool # # Uses `DB::Pool` for the pooling logic abstract struct BaseConnectionPool(PoolClient) - # Returns the max size of the connection pool - getter max_capacity : Int32 - - # Returns the configured checkout time out - getter timeout : Float64 - - # Creates a connection pool with the provided options + # Creates a connection pool with the provided options, and client factory block. def initialize( - @max_capacity : Int32 = 5, - @idle_capacity : Int32? = nil, - @timeout : Float64 = 5.0, + *, + max_capacity : Int32 = 5, + idle_capacity : Int32? = nil, + timeout : Float64 = 5.0, + &client_factory : -> PoolClient ) - @pool = build_pool() - end - - # Returns the idle capacity for the connection pool; if unset this is the same as `max_capacity`. - # - # This means that when idle capacity is unset the pool will keep all connections around forever, all the - # way until it reaches max capacity. - def idle_capacity : Int32 - if (idle = @idle_capacity).nil? - return @max_capacity + if idle_capacity.nil? + idle_capacity = max_capacity end - return idle + pool_options = DB::Pool::Options.new( + initial_pool_size: 0, + max_pool_size: max_capacity, + max_idle_pool_size: idle_capacity, + checkout_timeout: timeout + ) + + @pool = DB::Pool(PoolClient).new(pool_options, &client_factory) end # Returns the underlying `DB::Pool` object @@ -85,43 +80,22 @@ module Invidious::ConnectionPool ensure pool.release(http_client) if http_client && client_exists_in_pool end - - # Builds a connection pool - private abstract def build_pool : DB::Pool(PoolClient) - - # Creates a `DB::Pool::Options` used for constructing `DB::Pool` - private def pool_options : DB::Pool::Options - return DB::Pool::Options.new( - initial_pool_size: 0, - max_pool_size: max_capacity, - max_idle_pool_size: idle_capacity, - checkout_timeout: timeout - ) - end end # A basic connection pool where each client within is set to connect to a single resource struct Pool < BaseConnectionPool(HTTP::Client) - # The url each client within the pool will connect to - getter url : URI getter pool : DB::Pool(HTTP::Client) # Creates a pool of clients that connects to the given url, with the provided options. def initialize( url : URI, *, - @max_capacity : Int32 = 5, - @idle_capacity : Int32? = nil, - @timeout : Float64 = 5.0, + max_capacity : Int32 = 5, + idle_capacity : Int32? = nil, + timeout : Float64 = 5.0, ) - @url = url - @pool = build_pool() - end - - # :inherit: - private def build_pool : DB::Pool(HTTP::Client) - return DB::Pool(HTTP::Client).new(pool_options) do - make_client(url, force_resolve: true) + super(max_capacity: max_capacity, idle_capacity: idle_capacity, timeout: timeout) do + next make_client(url, force_resolve: true) end end end @@ -133,11 +107,16 @@ module Invidious::ConnectionPool struct CompanionPool < BaseConnectionPool(HTTP::Client) getter pool : DB::Pool(HTTP::Client) - # :inherit: - private def build_pool : DB::Pool(HTTP::Client) - return DB::Pool(HTTP::Client).new(pool_options) do + # Creates a pool of clients with the provided options. + def initialize( + *, + max_capacity : Int32 = 5, + idle_capacity : Int32? = nil, + timeout : Float64 = 5.0, + ) + super(max_capacity: max_capacity, idle_capacity: idle_capacity, timeout: timeout) do companion = CONFIG.invidious_companion.sample - make_client(companion.private_url, use_http_proxy: false) + next make_client(companion.private_url, use_http_proxy: false) end end end