Class: Wurk::RedisPool

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

Overview

Per-process pool over redis-client + connection_pool. Never share a socket across forks: the parent closes the pool before fork, each child opens a fresh one (see docs/idea/03-process-model.md, steps 3 and 5).

Retry policy on conn-level errors: close + retry once for messages prefixed READONLY / NOREPLICAS / UNBLOCKED. Spec: docs/target/sidekiq-free.md ยง26.

Constant Summary collapse

DEFAULT_URL =
ENV.fetch('REDIS_URL', 'redis://localhost:6379/0')
DEFAULT_TIMEOUT =
1.0
DEFAULT_NAME =
'default'
RETRYABLE_MSG =

Server-side messages where Sidekiq (and therefore Wurk) closes the connection and retries the block exactly once. Any other RedisClient::Error propagates immediately.

/\A(READONLY|NOREPLICAS|UNBLOCKED)/

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(size:, url: DEFAULT_URL, timeout: DEFAULT_TIMEOUT, name: DEFAULT_NAME) ⇒ RedisPool

Returns a new instance of RedisPool.



25
26
27
28
29
30
31
# File 'lib/wurk/redis_pool.rb', line 25

def initialize(size:, url: DEFAULT_URL, timeout: DEFAULT_TIMEOUT, name: DEFAULT_NAME)
  @size    = size
  @url     = url
  @timeout = timeout
  @name    = name
  @pool    = ConnectionPool.new(size: size, timeout: timeout) { build_client }
end

Instance Attribute Details

#nameObject (readonly)

Returns the value of attribute name.



23
24
25
# File 'lib/wurk/redis_pool.rb', line 23

def name
  @name
end

#sizeObject (readonly)

Returns the value of attribute size.



23
24
25
# File 'lib/wurk/redis_pool.rb', line 23

def size
  @size
end

#timeoutObject (readonly)

Returns the value of attribute timeout.



23
24
25
# File 'lib/wurk/redis_pool.rb', line 23

def timeout
  @timeout
end

#urlObject (readonly)

Returns the value of attribute url.



23
24
25
# File 'lib/wurk/redis_pool.rb', line 23

def url
  @url
end

Instance Method Details

#disconnect!Object



49
50
51
# File 'lib/wurk/redis_pool.rb', line 49

def disconnect!
  @pool.shutdown { |conn| safe_close(conn) }
end

#infoObject



53
54
55
# File 'lib/wurk/redis_pool.rb', line 53

def info
  with { |conn| parse_info(conn.call('INFO')) }
end

#withObject



33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
# File 'lib/wurk/redis_pool.rb', line 33

def with
  @pool.with do |conn|
    attempts = 0
    begin
      yield conn
    rescue RedisClient::Error => e
      raise unless RETRYABLE_MSG.match?(e.message.to_s)
      raise if attempts >= 1

      attempts += 1
      safe_close(conn)
      retry
    end
  end
end