Class: Octopus::Proxy

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

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(config) ⇒ Proxy

Returns a new instance of Proxy.



4
5
6
7
# File 'lib/octopus/proxy.rb', line 4

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

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(method, *args, &block) ⇒ Object



133
134
135
136
137
138
139
140
141
142
143
144
# File 'lib/octopus/proxy.rb', line 133

def method_missing(method, *args, &block)
  if should_clean_connection?(method)
    conn = select_connection()
    self.last_current_shard = self.current_shard
    clean_proxy()
    conn.send(method, *args, &block)
  elsif should_send_queries_to_replicated_databases?(method)
    send_queries_to_selected_slave(method, *args, &block)      
  else
    select_connection().send(method, *args, &block)
  end
end

Instance Attribute Details

#blockObject

Returns the value of attribute block.



2
3
4
# File 'lib/octopus/proxy.rb', line 2

def block
  @block
end

#configObject

Returns the value of attribute config.



2
3
4
# File 'lib/octopus/proxy.rb', line 2

def config
  @config
end

#current_groupObject

Returns the value of attribute current_group.



2
3
4
# File 'lib/octopus/proxy.rb', line 2

def current_group
  @current_group
end

#current_modelObject

Returns the value of attribute current_model.



2
3
4
# File 'lib/octopus/proxy.rb', line 2

def current_model
  @current_model
end

#current_shardObject

Returns the value of attribute current_shard.



2
3
4
# File 'lib/octopus/proxy.rb', line 2

def current_shard
  @current_shard
end

#last_current_shardObject

Returns the value of attribute last_current_shard.



2
3
4
# File 'lib/octopus/proxy.rb', line 2

def last_current_shard
  @last_current_shard
end

#using_enabledObject

Returns the value of attribute using_enabled.



2
3
4
# File 'lib/octopus/proxy.rb', line 2

def using_enabled
  @using_enabled
end

Instance Method Details

#check_schema_migrations(shard) ⇒ Object



117
118
119
120
121
# File 'lib/octopus/proxy.rb', line 117

def check_schema_migrations(shard)
  if !ActiveRecord::Base.using(shard).connection.table_exists?(ActiveRecord::Migrator.schema_migrations_table_name())
    ActiveRecord::Base.using(shard).connection.initialize_schema_migrations_table 
  end
end

#clean_proxyObject



110
111
112
113
114
115
# File 'lib/octopus/proxy.rb', line 110

def clean_proxy()
  @using_enabled = nil
  @current_shard = :master
  @current_group = nil
  @block = false
end

#initialize_replication(config) ⇒ Object



46
47
48
49
50
51
52
53
54
55
# File 'lib/octopus/proxy.rb', line 46

def initialize_replication(config)
  @replicated = true
  if config.has_key?("fully_replicated")
    @fully_replicated = config["fully_replicated"]
  else
    @fully_replicated = true
  end
  @slaves_list = @shards.keys.map {|sym| sym.to_s}.sort 
  @slaves_list.delete('master')   
end

#initialize_shards(config) ⇒ Object



9
10
11
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
# File 'lib/octopus/proxy.rb', line 9

def initialize_shards(config)
  @shards = {}
  @groups = {}
  @shards[:master] = ActiveRecord::Base.connection_pool()
  @config = ActiveRecord::Base.connection_pool.connection.instance_variable_get(:@config)
  @current_shard = :master
  
  if !config.nil? && config.has_key?("verify_connection")
    @verify_connection = config["verify_connection"]
  else
    @verify_connection = false
  end
  
  if !config.nil?
    @entire_sharded = config['entire_sharded']  
    shards_config = config[Octopus.rails_env()] 
  end
  
  shards_config ||= []

  shards_config.each do |key, value|
    if value.has_key?("adapter")
      initialize_adapter(value['adapter'])
      @shards[key.to_sym] = connection_pool_for(value, "#{value['adapter']}_connection")
    else
      @groups[key.to_sym] = []

      value.each do |k, v|
        raise "You have duplicated shard names!" if @shards.has_key?(k.to_sym)
        initialize_adapter(v['adapter'])
        @shards[k.to_sym] = connection_pool_for(v, "#{v['adapter']}_connection")
        @groups[key.to_sym] << k.to_sym
      end
    end
  end
end

#run_queries_on_shard(shard, &block) ⇒ Object



90
91
92
93
94
95
96
97
98
99
100
101
102
# File 'lib/octopus/proxy.rb', line 90

def run_queries_on_shard(shard, &block)
  older_shard = self.current_shard
  last_block = self.block

  begin
    self.block = true
    self.current_shard = shard
    yield
  ensure
    self.block = last_block || false
    self.current_shard = older_shard
  end
end

#select_connectionObject



81
82
83
84
# File 'lib/octopus/proxy.rb', line 81

def select_connection()
  @shards[shard_name].verify_active_connections! if @verify_connection 
  @shards[shard_name].connection()
end

#send_queries_to_multiple_shards(shards, &block) ⇒ Object



104
105
106
107
108
# File 'lib/octopus/proxy.rb', line 104

def send_queries_to_multiple_shards(shards, &block)
  shards.each do |shard|
    self.run_queries_on_shard(shard, &block)
  end
end

#shard_nameObject



86
87
88
# File 'lib/octopus/proxy.rb', line 86

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

#transaction(options = {}, &block) ⇒ Object



123
124
125
126
127
128
129
130
131
# File 'lib/octopus/proxy.rb', line 123

def transaction(options = {}, &block)
  if @replicated && (current_model.read_inheritable_attribute(:replicated) || @fully_replicated)
    self.run_queries_on_shard(:master) do
      select_connection.transaction(options, &block)
    end
  else
    select_connection.transaction(options, &block)
  end
end