Class: Octopus::ProxyConfig

Inherits:
Object
  • Object
show all
Defined in:
lib/octopus/proxy_config.rb

Constant Summary collapse

CURRENT_MODEL_KEY =
'octopus.current_model'.freeze
CURRENT_SHARD_KEY =
'octopus.current_shard'.freeze
CURRENT_GROUP_KEY =
'octopus.current_group'.freeze
CURRENT_SLAVE_GROUP_KEY =
'octopus.current_slave_group'.freeze
CURRENT_LOAD_BALANCE_OPTIONS_KEY =
'octopus.current_load_balance_options'.freeze
BLOCK_KEY =
'octopus.block'.freeze
FULLY_REPLICATED_KEY =
'octopus.fully_replicated'.freeze

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(config) ⇒ ProxyConfig

Returns a new instance of ProxyConfig.


15
16
17
18
# File 'lib/octopus/proxy_config.rb', line 15

def initialize(config)
  initialize_shards(config)
  initialize_replication(config) if !config.nil? && config['replicated']
end

Instance Attribute Details

#adaptersObject

Returns the value of attribute adapters


11
12
13
# File 'lib/octopus/proxy_config.rb', line 11

def adapters
  @adapters
end

#configObject

Returns the value of attribute config


11
12
13
# File 'lib/octopus/proxy_config.rb', line 11

def config
  @config
end

#entire_shardedObject

Returns the value of attribute entire_sharded


11
12
13
# File 'lib/octopus/proxy_config.rb', line 11

def entire_sharded
  @entire_sharded
end

#groupsObject

Returns the value of attribute groups


11
12
13
# File 'lib/octopus/proxy_config.rb', line 11

def groups
  @groups
end

#replicatedObject

Returns the value of attribute replicated


11
12
13
# File 'lib/octopus/proxy_config.rb', line 11

def replicated
  @replicated
end

#shardedObject

Returns the value of attribute sharded


11
12
13
# File 'lib/octopus/proxy_config.rb', line 11

def sharded
  @sharded
end

#shardsObject

Returns the value of attribute shards


11
12
13
# File 'lib/octopus/proxy_config.rb', line 11

def shards
  @shards
end

#shards_configObject

Returns the value of attribute shards_config


11
12
13
# File 'lib/octopus/proxy_config.rb', line 11

def shards_config
  @shards_config
end

#shards_slave_groupsObject

Returns the value of attribute shards_slave_groups


11
12
13
# File 'lib/octopus/proxy_config.rb', line 11

def shards_slave_groups
  @shards_slave_groups
end

#slave_groupsObject

Returns the value of attribute slave_groups


11
12
13
# File 'lib/octopus/proxy_config.rb', line 11

def slave_groups
  @slave_groups
end

#slaves_listObject

Returns the value of attribute slaves_list


11
12
13
# File 'lib/octopus/proxy_config.rb', line 11

def slaves_list
  @slaves_list
end

#slaves_load_balancerObject

Returns the value of attribute slaves_load_balancer


11
12
13
# File 'lib/octopus/proxy_config.rb', line 11

def slaves_load_balancer
  @slaves_load_balancer
end

Instance Method Details

#blockObject


95
96
97
# File 'lib/octopus/proxy_config.rb', line 95

def block
  Thread.current[BLOCK_KEY]
end

#block=(block) ⇒ Object


99
100
101
# File 'lib/octopus/proxy_config.rb', line 99

def block=(block)
  Thread.current[BLOCK_KEY] = block
end

#current_groupObject


65
66
67
# File 'lib/octopus/proxy_config.rb', line 65

def current_group
  Thread.current[CURRENT_GROUP_KEY]
end

#current_group=(group_symbol) ⇒ Object


69
70
71
72
73
74
75
76
# File 'lib/octopus/proxy_config.rb', line 69

def current_group=(group_symbol)
  # TODO: Error message should include all groups if given more than one bad name.
  [group_symbol].flatten.compact.each do |group|
    fail "Nonexistent Group Name: #{group}" unless has_group?(group)
  end

  Thread.current[CURRENT_GROUP_KEY] = group_symbol
end

#current_load_balance_optionsObject


87
88
89
# File 'lib/octopus/proxy_config.rb', line 87

def current_load_balance_options
  Thread.current[CURRENT_LOAD_BALANCE_OPTIONS_KEY]
end

#current_load_balance_options=(options) ⇒ Object


91
92
93
# File 'lib/octopus/proxy_config.rb', line 91

def current_load_balance_options=(options)
  Thread.current[CURRENT_LOAD_BALANCE_OPTIONS_KEY] = options
end

#current_modelObject


20
21
22
# File 'lib/octopus/proxy_config.rb', line 20

def current_model
  Thread.current[CURRENT_MODEL_KEY]
end

#current_model=(model) ⇒ Object


24
25
26
# File 'lib/octopus/proxy_config.rb', line 24

def current_model=(model)
  Thread.current[CURRENT_MODEL_KEY] = model.is_a?(ActiveRecord::Base) ? model.class : model
end

#current_shardObject


28
29
30
# File 'lib/octopus/proxy_config.rb', line 28

def current_shard
  Thread.current[CURRENT_SHARD_KEY] ||= Octopus.master_shard
end

#current_shard=(shard_symbol) ⇒ Object


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
# File 'lib/octopus/proxy_config.rb', line 32

def current_shard=(shard_symbol)
  if shard_symbol.is_a?(Array)
    self.current_slave_group = nil
    shard_symbol.each { |symbol| fail "Nonexistent Shard Name: #{symbol}" if shards[symbol].nil? }
  elsif shard_symbol.is_a?(Hash)
    hash = shard_symbol
    shard_symbol = hash[:shard]
    slave_group_symbol = hash[:slave_group]
    load_balance_options = hash[:load_balance_options]

    if shard_symbol.nil? && slave_group_symbol.nil?
      fail 'Neither shard or slave group must be specified'
    end

    if shard_symbol.present?
      fail "Nonexistent Shard Name: #{shard_symbol}" if shards[shard_symbol].nil?
    end

    if slave_group_symbol.present?
      if (shards_slave_groups.try(:[], shard_symbol).present? && shards_slave_groups[shard_symbol][slave_group_symbol].nil?) ||
          (shards_slave_groups.try(:[], shard_symbol).nil? && @slave_groups[slave_group_symbol].nil?)
        fail "Nonexistent Slave Group Name: #{slave_group_symbol} in shards config: #{shards_config.inspect}"
      end
    end
    self.current_slave_group = slave_group_symbol
    self.current_load_balance_options = load_balance_options
  else
    fail "Nonexistent Shard Name: #{shard_symbol}" if shards[shard_symbol].nil?
  end

  Thread.current[CURRENT_SHARD_KEY] = shard_symbol
end

#current_slave_groupObject


78
79
80
# File 'lib/octopus/proxy_config.rb', line 78

def current_slave_group
  Thread.current[CURRENT_SLAVE_GROUP_KEY]
end

#current_slave_group=(slave_group_symbol) ⇒ Object


82
83
84
85
# File 'lib/octopus/proxy_config.rb', line 82

def current_slave_group=(slave_group_symbol)
  Thread.current[CURRENT_SLAVE_GROUP_KEY] = slave_group_symbol
  Thread.current[CURRENT_LOAD_BALANCE_OPTIONS_KEY] = nil if slave_group_symbol.nil?
end

#fully_replicated?Boolean

Returns:

  • (Boolean)

103
104
105
# File 'lib/octopus/proxy_config.rb', line 103

def fully_replicated?
  @fully_replicated || Thread.current[FULLY_REPLICATED_KEY]
end

#has_group?(group) ⇒ Boolean

Public: Whether or not a group exists with the given name converted to a string.

Returns a boolean.

Returns:

  • (Boolean)

111
112
113
# File 'lib/octopus/proxy_config.rb', line 111

def has_group?(group)
  @groups.key?(group.to_s)
end

#initialize_replication(config) ⇒ Object


200
201
202
203
204
205
206
207
208
209
210
211
# File 'lib/octopus/proxy_config.rb', line 200

def initialize_replication(config)
  @replicated = true
  if config.key?('fully_replicated')
    @fully_replicated = config['fully_replicated']
  else
    @fully_replicated = true
  end

  @slaves_list = shards.keys.map(&:to_s).sort
  @slaves_list.delete('master')
  @slaves_load_balancer = Octopus.load_balancer.new(@slaves_list)
end

#initialize_shards(config) ⇒ Object


134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
# File 'lib/octopus/proxy_config.rb', line 134

def initialize_shards(config)
  @original_config = config

  self.shards = HashWithIndifferentAccess.new
  self.shards_slave_groups = HashWithIndifferentAccess.new
  self.slave_groups = HashWithIndifferentAccess.new
  self.groups = {}
  self.config = ActiveRecord::Base.connection_pool_without_octopus.spec.config

  unless config.nil?
    self.entire_sharded = config['entire_sharded']
    self.shards_config = config[Octopus.rails_env]
  end

  self.shards_config ||= []

  shards_config.each do |key, value|
    if value.is_a?(String)
      value = resolve_string_connection(value).merge(:octopus_shard => key)
      initialize_adapter(value['adapter'])
      shards[key.to_sym] = connection_pool_for(value, "#{value['adapter']}_connection")
    elsif value.is_a?(Hash) && value.key?('adapter')
      value.merge!(:octopus_shard => key)
      initialize_adapter(value['adapter'])
      shards[key.to_sym] = connection_pool_for(value, "#{value['adapter']}_connection")

      slave_group_configs = value.select do |_k, v|
        structurally_slave_group? v
      end

      if slave_group_configs.present?
        slave_groups = HashWithIndifferentAccess.new
        slave_group_configs.each do |slave_group_name, slave_configs|
          slaves = HashWithIndifferentAccess.new
          slave_configs.each do |slave_name, slave_config|
            shards[slave_name.to_sym] = connection_pool_for(slave_config, "#{value['adapter']}_connection")
            slaves[slave_name.to_sym] = slave_name.to_sym
          end
          slave_groups[slave_group_name.to_sym] = Octopus::SlaveGroup.new(slaves)
        end
        @shards_slave_groups[key.to_sym] = slave_groups
        @sharded = true
      end
    elsif value.is_a?(Hash)
      @groups[key.to_s] = []

      value.each do |k, v|
        fail 'You have duplicated shard names!' if shards.key?(k.to_sym)

        initialize_adapter(v['adapter'])
        config_with_octopus_shard = v.merge(:octopus_shard => k)

        shards[k.to_sym] = connection_pool_for(config_with_octopus_shard, "#{v['adapter']}_connection")
        @groups[key.to_s] << k.to_sym
      end

      if structurally_slave_group? value
        slaves = Hash[@groups[key.to_s].map { |v| [v, v] }]
        @slave_groups[key.to_sym] = Octopus::SlaveGroup.new(slaves)
      end
    end
  end

  shards[:master] ||= ActiveRecord::Base.connection_pool_without_octopus if Octopus.master_shard == :master
end

#reinitialize_shardsObject


213
214
215
# File 'lib/octopus/proxy_config.rb', line 213

def reinitialize_shards
  initialize_shards(@original_config)
end

#shard_nameObject


122
123
124
# File 'lib/octopus/proxy_config.rb', line 122

def shard_name
  current_shard.is_a?(Array) ? current_shard.first : current_shard
end

#shard_namesObject

Public: Retrieves names of all loaded shards.

Returns an array of shard names as symbols


118
119
120
# File 'lib/octopus/proxy_config.rb', line 118

def shard_names
  shards.keys
end

#shards_for_group(group) ⇒ Object

Public: Retrieves the defined shards for a given group.

Returns an array of shard names as symbols or nil if the group is not defined.


130
131
132
# File 'lib/octopus/proxy_config.rb', line 130

def shards_for_group(group)
  @groups.fetch(group.to_s, nil)
end