Class: Multidb::Balancer

Inherits:
Object
  • Object
show all
Defined in:
lib/multidb/balancer.rb

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(configuration) ⇒ Balancer

Returns a new instance of Balancer.



7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# File 'lib/multidb/balancer.rb', line 7

def initialize(configuration)
  @candidates = {}.with_indifferent_access
  @default_configuration = configuration

  return unless @default_configuration

  append(@default_configuration.raw_configuration[:databases] || {})

  @fallback = if @default_configuration.raw_configuration.include?(:fallback)
                @default_configuration.raw_configuration[:fallback]
              elsif defined?(Rails)
                %w[development test].include?(Rails.env)
              else
                false
              end

  @default_candidate = Candidate.new('default', @default_configuration.default_handler)

  @candidates[:default] = [@default_candidate] unless @candidates.include?(:default)
end

Instance Attribute Details

#fallbackObject

Returns the value of attribute fallback.



5
6
7
# File 'lib/multidb/balancer.rb', line 5

def fallback
  @fallback
end

Class Method Details

.current_connectionObject



109
110
111
# File 'lib/multidb/balancer.rb', line 109

def current_connection
  Multidb.balancer.current_connection
end

.current_connection_nameObject



113
114
115
# File 'lib/multidb/balancer.rb', line 113

def current_connection_name
  Multidb.balancer.current_connection_name
end

.disconnect!Object



117
118
119
# File 'lib/multidb/balancer.rb', line 117

def disconnect!
  Multidb.balancer.disconnect!
end

.use(name, &block) ⇒ Object



105
106
107
# File 'lib/multidb/balancer.rb', line 105

def use(name, &block)
  Multidb.balancer.use(name, &block)
end

Instance Method Details

#append(databases) ⇒ Object



28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
# File 'lib/multidb/balancer.rb', line 28

def append(databases)
  databases.each_pair do |name, config|
    configs = config.is_a?(Array) ? config : [config]
    configs.each do |cfg|
      if cfg['alias']
        @candidates[name] = @candidates[cfg['alias']]
        next
      end

      candidate = Candidate.new(name, @default_configuration.default_adapter.merge(cfg))
      @candidates[name] ||= []
      @candidates[name].push(candidate)
    end
  end
end

#current_connectionObject



88
89
90
91
92
93
94
# File 'lib/multidb/balancer.rb', line 88

def current_connection
  if Thread.current[:multidb]
    Thread.current[:multidb][:connection]
  else
    @default_candidate.connection
  end
end

#current_connection_nameObject



96
97
98
99
100
101
102
# File 'lib/multidb/balancer.rb', line 96

def current_connection_name
  if Thread.current[:multidb]
    Thread.current[:multidb][:connection_name]
  else
    :default
  end
end

#disconnect!Object



44
45
46
# File 'lib/multidb/balancer.rb', line 44

def disconnect!
  @candidates.values.flatten.each(&:disconnect!)
end

#get(name, &_block) ⇒ Object

Raises:

  • (ArgumentError)


48
49
50
51
52
53
54
55
56
57
# File 'lib/multidb/balancer.rb', line 48

def get(name, &_block)
  candidates = @candidates[name]
  candidates ||= @fallback ? @candidates[:default] : []

  raise ArgumentError, "No such database connection '#{name}'" if candidates.empty?

  candidate = candidates.respond_to?(:sample) ? candidates.sample : candidates[rand(candidates.length)]

  block_given? ? yield(candidate) : candidate
end

#use(name, &_block) ⇒ Object



59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
# File 'lib/multidb/balancer.rb', line 59

def use(name, &_block)
  result = nil
  get(name) do |candidate|
    if block_given?
      candidate.connection do |connection|
        previous_configuration = Thread.current[:multidb]
        Thread.current[:multidb] = {
          connection: connection,
          connection_name: name
        }
        begin
          result = yield
          result = result.to_a if result.is_a?(ActiveRecord::Relation)
        ensure
          Thread.current[:multidb] = previous_configuration
        end
        result
      end
    else
      Thread.current[:multidb] = {
        connection: candidate.connection,
        connection_name: name
      }
      result = candidate.connection
    end
  end
  result
end