Module: Wurk::RedisOptions
- Defined in:
- lib/wurk/redis_options.rb
Overview
Translates a Sidekiq-shaped config.redis hash into the exact keyword set
redis-client accepts.
Sidekiq normalizes the hash itself before handing it over
(sidekiq/redis_client_adapter.rb#client_opts), so initializers in the wild
carry keys redis-client has never known. Wurk used to splat the hash straight
into RedisClient.config, which surfaced as
ArgumentError: unknown keyword: :network_timeout — and only inside the
forked children, which build their own pools (#283). The parent booted fine,
the liveness probe passed, and the swarm respawn loop churned forever
processing zero jobs. Hence validate!, called from Configuration#redis= so
a bad hash raises in the parent where someone can actually see it.
Reference: sidekiq 7.3 / 8.1 client_opts — namespace rejected,
size/pool_timeout dropped, network_timeout → timeout, master_name →
name, role/driver symbolized, reconnect_attempts ||= 1.
Constant Summary collapse
- POOL_KEYS =
Consumed by the pool layer (RedisPool / Capsule); never a socket concern.
%i[size name pool_name pool_timeout on_error].freeze
- IGNORED_KEYS =
Accepted for Sidekiq parity, then dropped: Sidekiq used
loggerfor its own "connecting to Redis with options ..." line andcluster_safeto unlock:nodes. redis-client has no keyword for either. %i[logger cluster_safe].freeze
- TRANSLATED_KEYS =
Sidekiq-only spellings this module rewrites into redis-client keywords.
%i[network_timeout master_name].freeze
- UMBRELLA_TIMEOUT_KEYS =
The umbrella socket timeout, under both its names.
network_timeoutis the redis-rb-era spelling every "widen the timeouts for a slow/remote Redis" snippet still uses;timeoutis redis-client's own. %i[network_timeout timeout].freeze
- SPLIT_TIMEOUT_KEYS =
Wurk splits the socket timeouts (#101) and passes all three explicitly, and redis-client lets an explicit
read_timeoutwin overtimeout— so forwarding the umbrella verbatim would silently drop the host's value. Fan it out instead; a host-supplied split timeout still wins over the fan-out. %i[connect_timeout read_timeout write_timeout].freeze
- SYMBOLIZED_KEYS =
Symbols in redis-client, strings in plenty of YAML-sourced configs.
%i[driver role].freeze
- REJECTED_KEYS =
Keys that mean something in Sidekiq but have no Wurk equivalent. Raise naming the key and its replacement — the alternative is an opaque
unknown keyword:from three layers down inside a forked child. { namespace: 'Redis namespacing was dropped in Sidekiq 7 and Wurk never implemented it ' \ '(docs/migrate-from-sidekiq.md §4). Give Wurk its own Redis database ' \ '(redis://host:6379/1) or its own instance instead.', nodes: 'Wurk does not run on Redis Cluster. Point config.redis at a single server with ' \ '`url:`, or at a Sentinel set with `sentinels:`.' }.freeze
- KEYWORD_PARAMS =
Keyword parameter kinds in Method#parameters.
%i[key keyreq].freeze
Class Method Summary collapse
-
.fiber_blocking_driver?(driver) ⇒ Boolean
driver: :hiredis, the C driver a fiber scheduler cannot switch away from. -
.known_keys ⇒ Object
Every keyword redis-client itself accepts, read off its own signatures so the list can't drift from the installed version.
-
.normalize(options, defaults: {}) ⇒ Object
The keyword hash for RedisClient.config / RedisClient.sentinel.
-
.pool_kwargs(options) ⇒ Object
The keyword set a
config.redis-shaped hash hands to RedisPool.new, whose ownname:is its telemetry label (Sidekiq'spool_name:). -
.sentinel?(client_config) ⇒ Boolean
Sentinel sets go through RedisClient.sentinel — RedisClient.config rejects
sentinels:outright. -
.validate!(options) ⇒ Object
Raises for anything redis-client would reject.
Class Method Details
.fiber_blocking_driver?(driver) ⇒ Boolean
driver: :hiredis, the C driver a fiber scheduler cannot switch away from.
113 114 115 |
# File 'lib/wurk/redis_options.rb', line 113 def fiber_blocking_driver?(driver) driver.to_s.include?('hiredis') end |
.known_keys ⇒ Object
Every keyword redis-client itself accepts, read off its own signatures so the list can't drift from the installed version. Config#initialize takes a **kwargs rest and forwards to Config::Common, so both have to be walked; SentinelConfig adds the sentinel-only keys.
127 128 129 130 131 |
# File 'lib/wurk/redis_options.rb', line 127 def known_keys @known_keys ||= [ ::RedisClient::Config, ::RedisClient::Config::Common, ::RedisClient::SentinelConfig ].flat_map { |mod| keyword_params(mod) }.union(POOL_KEYS, IGNORED_KEYS, TRANSLATED_KEYS) end |
.normalize(options, defaults: {}) ⇒ Object
The keyword hash for RedisClient.config / RedisClient.sentinel.
defaults are Wurk's own socket defaults; everything the host supplied
wins over them.
66 67 68 69 70 71 72 73 74 75 76 77 |
# File 'lib/wurk/redis_options.rb', line 66 def normalize(, defaults: {}) opts = symbolize() validate!(opts) opts = translate(opts) # The default `url` survives next to a sentinel set, as in Sidekiq # (`url ||= REDIS_URL`): SentinelConfig reads the db and credentials off # it and falls back to its host for the master name, so # REDIS_URL=redis://mymaster/2 plus `sentinels:` is a working config. # An explicit `name:` still wins over the url's host. defaults.merge(split_timeouts(opts), opts.except(*UMBRELLA_TIMEOUT_KEYS)) end |
.pool_kwargs(options) ⇒ Object
The keyword set a config.redis-shaped hash hands to RedisPool.new,
whose own name: is its telemetry label (Sidekiq's pool_name:).
Sidekiq spells the Sentinel master name:, so next to sentinels: it is
carried as master_name — otherwise it would collide with the label
and never reach RedisClient.sentinel. An explicit master_name wins,
as it does in Sidekiq's own translation. Without sentinels name has no
redis-client meaning and is dropped; size and pool_name are the
caller's to place.
87 88 89 90 91 92 93 |
# File 'lib/wurk/redis_options.rb', line 87 def pool_kwargs() opts = symbolize() name = opts[:name] opts = opts.except(:size, :name, :pool_name) opts[:master_name] = name if name && sentinel?(opts) && !opts.key?(:master_name) opts end |
.sentinel?(client_config) ⇒ Boolean
Sentinel sets go through RedisClient.sentinel — RedisClient.config
rejects sentinels: outright. Same routing Sidekiq does.
119 120 121 |
# File 'lib/wurk/redis_options.rb', line 119 def sentinel?(client_config) client_config.key?(:sentinels) end |
.validate!(options) ⇒ Object
Raises for anything redis-client would reject. Cheap and pure, so it runs in the parent (Configuration#redis=) as well as at pool-build time.
97 98 99 100 101 102 103 104 105 106 107 108 109 110 |
# File 'lib/wurk/redis_options.rb', line 97 def validate!() opts = symbolize() REJECTED_KEYS.each do |key, hint| raise ArgumentError, "config.redis[:#{key}] is not supported. #{hint}" if opts.key?(key) end unknown = opts.keys - known_keys return if unknown.empty? raise ArgumentError, "config.redis: unknown option#{'s' if unknown.size > 1} " \ "#{unknown.map(&:inspect).join(', ')}. Supported keys: #{known_keys.sort.join(', ')}." end |