From 00600074bbf587a8883d4ab8aea966f417fe78a9 Mon Sep 17 00:00:00 2001 From: Lyle Davis Date: Mon, 20 Jan 2025 12:09:11 +0000 Subject: [PATCH] move redis pool setup into the constructor --- lib/eventq/eventq_base/nonce_manager.rb | 43 ++++++++++++++----------- spec/eventq_base/nonce_manager_spec.rb | 13 ++++++++ 2 files changed, 38 insertions(+), 18 deletions(-) diff --git a/lib/eventq/eventq_base/nonce_manager.rb b/lib/eventq/eventq_base/nonce_manager.rb index 7779d8c..33c9fd6 100644 --- a/lib/eventq/eventq_base/nonce_manager.rb +++ b/lib/eventq/eventq_base/nonce_manager.rb @@ -1,4 +1,6 @@ module EventQ + class NonceManagerNotConfiguredError < StandardError; end + class NonceManager def self.configure(server:,timeout:10000,lifespan:3600, pool_size: 5, pool_timeout: 5) @@ -7,6 +9,16 @@ def self.configure(server:,timeout:10000,lifespan:3600, pool_size: 5, pool_timeo @lifespan = lifespan @pool_size = pool_size @pool_timeout = pool_timeout + + @redis_pool = begin + require 'connection_pool' + require 'redis' + + ConnectionPool.new(size: @pool_size, timeout: @pool_timeout) do + Redis.new(url: @server_url) + end + end + @configured = true end def self.server_url @@ -31,7 +43,7 @@ def self.pool_timeout def self.lock(nonce) # act as if successfully locked if not nonce manager configured - makes it a no-op - return true if not_configured? + return true if !configured? successfully_locked = false with_redis_connection do |conn| @@ -48,7 +60,7 @@ def self.lock(nonce) # if the message was successfully procesed, lock for another lifespan length # so it isn't reprocessed def self.complete(nonce) - return true if not_configured? + return true if !configured? with_redis_connection do |conn| conn.expire(nonce, lifespan) @@ -59,7 +71,7 @@ def self.complete(nonce) # if it failed, unlock immediately so that retries can kick in def self.failed(nonce) - return true if not_configured? + return true if !configured? with_redis_connection do |conn| conn.del(nonce) @@ -74,29 +86,24 @@ def self.reset @lifespan = nil @pool_size = nil @pool_timeout = nil + @configured = false + @redis_pool.reload(&:close) + end + + def self.configured? + @configured == true end private def self.with_redis_connection - redis_pool.with do |conn| - yield conn + if !configured? + raise NonceManagerNotConfiguredError, 'Unable to checkout redis connection from pool, nonce manager has not been configured. Call .configure on NonceManager.' end - end - - def self.redis_pool - @redis_pool ||= begin - require 'connection_pool' - require 'redis' - ConnectionPool.new(size: @pool_size, timeout: @pool_timeout) do - Redis.new(url: @server_url) - end + @redis_pool.with do |conn| + yield conn end end - - def self.not_configured? - @server_url.nil? || @server_url.empty? - end end end diff --git a/spec/eventq_base/nonce_manager_spec.rb b/spec/eventq_base/nonce_manager_spec.rb index 17fdc5d..432eac4 100644 --- a/spec/eventq_base/nonce_manager_spec.rb +++ b/spec/eventq_base/nonce_manager_spec.rb @@ -134,4 +134,17 @@ end end + # this is a private method, but we want to make sure we correctly raise an error if a consumer tries to use + # it directly to access the underlying connection pool without configuring the nonce manager first + describe '.with_redis_connection' do + context 'when the nonce manager has not been configured' do + before do + described_class.reset + end + + it 'raises error' do + expect { described_class.with_redis_connection { } }.to raise_error(EventQ::NonceManagerNotConfiguredError) + end + end + end end