Class: RedisClient::SentinelConfig

Inherits:
Object
  • Object
show all
Includes:
Config::Common
Defined in:
lib/redis_client/sentinel_config.rb

Constant Summary collapse

SENTINEL_DELAY =
0.25
DEFAULT_RECONNECT_ATTEMPTS =
2

Instance Attribute Summary collapse

Attributes included from Config::Common

#circuit_breaker, #command_builder, #connect_timeout, #custom, #db, #driver, #id, #inherit_socket, #middlewares_stack, #protocol, #read_timeout, #ssl, #ssl_params, #write_timeout

Instance Method Summary collapse

Methods included from Config::Common

#connection_prelude, #new_client, #new_pool, #password, #retriable?, #server_url, #ssl_context, #username

Constructor Details

#initialize(sentinels:, sentinel_password: nil, sentinel_username: nil, role: :master, name: nil, url: nil, **client_config) ⇒ SentinelConfig

Returns a new instance of SentinelConfig.



12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
# File 'lib/redis_client/sentinel_config.rb', line 12

def initialize(
  sentinels:,
  sentinel_password: nil,
  sentinel_username: nil,
  role: :master,
  name: nil,
  url: nil,
  **client_config
)
  unless i(master replica slave).include?(role.to_sym)
    raise ArgumentError, "Expected role to be either :master or :replica, got: #{role.inspect}"
  end

  if url
    url_config = URLConfig.new(url)
    client_config = {
      username: url_config.username,
      password: url_config.password,
      db: url_config.db,
    }.compact.merge(client_config)
    name ||= url_config.host
  end

  @name = name
  unless @name
    raise ArgumentError, "RedisClient::SentinelConfig requires either a name or an url with a host"
  end

  @to_list_of_hash = @to_hash = nil
  password = if sentinel_password && !sentinel_password.respond_to?(:call)
    ->(_) { sentinel_password }
  else
    sentinel_password
  end
  @extra_config = {
    username: sentinel_username,
    password: password,
    db: nil,
  }
  if client_config[:protocol] == 2
    @extra_config[:protocol] = client_config[:protocol]
    @to_list_of_hash = lambda do |may_be_a_list|
      if may_be_a_list.is_a?(Array)
        may_be_a_list.map { |l| l.each_slice(2).to_h }
      else
        may_be_a_list
      end
    end
  end

  @sentinels = {}.compare_by_identity
  @role = role.to_sym
  @mutex = Mutex.new
  @config = nil

  client_config[:reconnect_attempts] ||= DEFAULT_RECONNECT_ATTEMPTS
  @client_config = client_config || {}
  super(**client_config)
  @sentinel_configs = sentinels_to_configs(sentinels)
end

Instance Attribute Details

#nameObject (readonly)

Returns the value of attribute name.



10
11
12
# File 'lib/redis_client/sentinel_config.rb', line 10

def name
  @name
end

Instance Method Details

#check_role!(role) ⇒ Object



110
111
112
113
114
115
116
117
118
119
120
121
122
# File 'lib/redis_client/sentinel_config.rb', line 110

def check_role!(role)
  if @role == :master
    unless role == "master"
      sleep SENTINEL_DELAY
      raise FailoverError, "Expected to connect to a master, but the server is a replica"
    end
  else
    unless role == "slave"
      sleep SENTINEL_DELAY
      raise FailoverError, "Expected to connect to a replica, but the server is a master"
    end
  end
end

#hostObject



89
90
91
# File 'lib/redis_client/sentinel_config.rb', line 89

def host
  config.host
end

#pathObject



97
98
99
# File 'lib/redis_client/sentinel_config.rb', line 97

def path
  nil
end

#portObject



93
94
95
# File 'lib/redis_client/sentinel_config.rb', line 93

def port
  config.port
end

#resetObject



79
80
81
82
83
# File 'lib/redis_client/sentinel_config.rb', line 79

def reset
  @mutex.synchronize do
    @config = nil
  end
end

#resolved?Boolean

Returns:

  • (Boolean)


124
125
126
127
128
# File 'lib/redis_client/sentinel_config.rb', line 124

def resolved?
  @mutex.synchronize do
    !!@config
  end
end

#retry_connecting?(attempt, error) ⇒ Boolean

Returns:

  • (Boolean)


101
102
103
104
# File 'lib/redis_client/sentinel_config.rb', line 101

def retry_connecting?(attempt, error)
  reset unless error.is_a?(TimeoutError)
  super
end

#sentinel?Boolean

Returns:

  • (Boolean)


106
107
108
# File 'lib/redis_client/sentinel_config.rb', line 106

def sentinel?
  true
end

#sentinelsObject



73
74
75
76
77
# File 'lib/redis_client/sentinel_config.rb', line 73

def sentinels
  @mutex.synchronize do
    @sentinel_configs.dup
  end
end

#server_keyObject



85
86
87
# File 'lib/redis_client/sentinel_config.rb', line 85

def server_key
  config.server_key
end