Class: PatientHttp::Sidekiq::RedisPool

Inherits:
Object
  • Object
show all
Defined in:
lib/patient_http/sidekiq/redis_pool.rb

Overview

Dedicated Redis connection pool for the gem's own threads.

The processor's completion worker threads and the task monitor thread carry no Sidekiq capsule state, so plain Sidekiq.redis calls from them fall through to Sidekiq's small internal pool (10 connections, 1 second checkout timeout). Under load that pool becomes a serialization point and checkout timeouts can lose work. This pool is built from the application's own Sidekiq Redis configuration and is used for all registry, stats, and job pushes made from gem-owned threads.

Constant Summary collapse

DEFAULT_MINIMUM_SIZE =
10

Instance Method Summary collapse

Constructor Details

#initialize(config) ⇒ RedisPool

Returns a new instance of RedisPool.

Parameters:



18
19
20
21
22
23
# File 'lib/patient_http/sidekiq/redis_pool.rb', line 18

def initialize(config)
  @config = config
  @pid = nil
  @pool = nil
  @mutex = Mutex.new
end

Instance Method Details

#poolConnectionPool

The underlying ConnectionPool, created lazily and rebuilt after a process fork so child processes never share parent connections.

Returns:

  • (ConnectionPool)


29
30
31
32
33
34
35
36
37
# File 'lib/patient_http/sidekiq/redis_pool.rb', line 29

def pool
  @mutex.synchronize do
    if @pool.nil? || @pid != ::Process.pid
      @pool = ::Sidekiq.default_configuration.new_redis_pool(size, "patient_http")
      @pid = ::Process.pid
    end
    @pool
  end
end

#shutdownvoid

This method returns an undefined value.

Close all connections and drop the pool.



68
69
70
71
72
73
74
# File 'lib/patient_http/sidekiq/redis_pool.rb', line 68

def shutdown
  @mutex.synchronize do
    @pool&.shutdown { |conn| conn.close }
    @pool = nil
    @pid = nil
  end
end

#with(retry_on_connection_error: true) {|conn| ... } ⇒ Object

Check out a connection with the gem's checkout timeout and yield it. A connection-level failure is retried once on a fresh checkout, mirroring the retry Sidekiq itself performs.

The retry replays the whole block, so callers whose block is not idempotent (counter increments, anything the server may already have applied before the connection dropped) must pass retry_on_connection_error: false and handle the failure themselves.

Parameters:

  • retry_on_connection_error (Boolean) (defaults to: true)

    whether to replay the block once after a connection-level failure

Yields:

  • (conn)

    the Redis connection

Returns:

  • (Object)

    the block's return value



52
53
54
55
56
57
58
59
60
61
62
63
# File 'lib/patient_http/sidekiq/redis_pool.rb', line 52

def with(retry_on_connection_error: true, &block)
  retryable = retry_on_connection_error
  begin
    pool.with(timeout: @config.redis_pool_timeout) do |conn|
      yield conn
    end
  rescue RedisClient::ConnectionError
    raise unless retryable
    retryable = false
    retry
  end
end