Class: Redis::Client::Connector::Sentinel
- Inherits:
-
Redis::Client::Connector
- Object
- Redis::Client::Connector
- Redis::Client::Connector::Sentinel
- Defined in:
- lib/redis/client.rb
Instance Method Summary collapse
- #check(client) ⇒ Object
-
#initialize(options) ⇒ Sentinel
constructor
A new instance of Sentinel.
- #resolve ⇒ Object
- #resolve_master ⇒ Object
- #resolve_slave ⇒ Object
- #sentinel_detect ⇒ Object
Constructor Details
#initialize(options) ⇒ Sentinel
Returns a new instance of Sentinel.
536 537 538 539 540 541 542 543 544 |
# File 'lib/redis/client.rb', line 536 def initialize() super() @options[:db] = DEFAULTS.fetch(:db) @sentinels = @options.delete(:sentinels).dup @role = @options.fetch(:role, "master").to_s @master = @options[:host] end |
Instance Method Details
#check(client) ⇒ Object
546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 |
# File 'lib/redis/client.rb', line 546 def check(client) # Check the instance is really of the role we are looking for. # We can't assume the command is supported since it was introduced # recently and this client should work with old stuff. begin role = client.call([:role])[0] rescue Redis::CommandError # Assume the test is passed if we can't get a reply from ROLE... role = @role end if role != @role client.disconnect raise ConnectionError, "Instance role mismatch. Expected #{@role}, got #{role}." end end |
#resolve ⇒ Object
563 564 565 566 567 568 569 570 571 572 573 574 |
# File 'lib/redis/client.rb', line 563 def resolve result = case @role when "master" resolve_master when "slave" resolve_slave else raise ArgumentError, "Unknown instance role #{@role}" end result || (raise ConnectionError, "Unable to fetch #{@role} via Sentinel.") end |
#resolve_master ⇒ Object
602 603 604 605 606 607 608 |
# File 'lib/redis/client.rb', line 602 def resolve_master sentinel_detect do |client| if reply = client.call(["sentinel", "get-master-addr-by-name", @master]) {:host => reply[0], :port => reply[1]} end end end |
#resolve_slave ⇒ Object
610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 |
# File 'lib/redis/client.rb', line 610 def resolve_slave sentinel_detect do |client| if reply = client.call(["sentinel", "slaves", @master]) slaves = reply.map { |s| s.each_slice(2).to_h } slaves.each { |s| s['flags'] = s.fetch('flags').split(',') } slaves.reject! { |s| s.fetch('flags').include?('s_down') } if slaves.empty? raise CannotConnectError, 'No slaves available.' else slave = slaves.sample { host: slave.fetch('ip'), port: slave.fetch('port'), } end end end end |
#sentinel_detect ⇒ Object
576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 |
# File 'lib/redis/client.rb', line 576 def sentinel_detect @sentinels.each do |sentinel| client = Client.new(@options.merge({ :host => sentinel[:host], :port => sentinel[:port], password: sentinel[:password], :reconnect_attempts => 0, })) begin if result = yield(client) # This sentinel responded. Make sure we ask it first next time. @sentinels.delete(sentinel) @sentinels.unshift(sentinel) return result end rescue BaseConnectionError ensure client.disconnect end end raise CannotConnectError, "No sentinels available." end |