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() if config[Octopus.env()] && config[Octopus.env()]["replicated"]
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

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



91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
# File 'lib/octopus/proxy.rb', line 91

def method_missing(method, *args, &block)
  if should_clean_connection?(method)
    conn = select_connection()
    self.last_current_shard = self.current_shard
    self.current_shard = :master
    @using_enabled = nil
    conn.send(method, *args, &block)
  elsif should_send_queries_to_replicated_databases?(method)
    send_queries_to_selected_slave(method, *args, &block)      
  elsif should_send_queries_to_multiple_groups?
    send_queries_to_multiple_groups(method, *args, &block)
  elsif should_send_queries_to_multiple_shards?
    send_queries_to_shards(current_shard, method, *args, &block)
  elsif should_send_queries_to_a_group_of_shards?
    send_queries_to_shards(@groups[current_group], 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

#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

#add_transaction_record(record) ⇒ Object



71
72
73
74
75
# File 'lib/octopus/proxy.rb', line 71

def add_transaction_record(record)
  if !select_connection().instance_variable_get(:@_current_transaction_records).nil?
    select_connection().add_transaction_record(record)
  end
end

#initialize_replicationObject



33
34
35
36
37
# File 'lib/octopus/proxy.rb', line 33

def initialize_replication()
  @replicated = true
  @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
# File 'lib/octopus/proxy.rb', line 9

def initialize_shards(config)
  @shards = {}
  @groups = {}
  @shards[:master] = ActiveRecord::Base.connection_pool()
  @current_shard = :master
  shards_config = config[Octopus.env()]["shards"] || []
  
  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



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

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

  begin
    yield
  ensure
    self.block = false
    self.current_shard = older_shard
  end
end

#select_connectionObject



63
64
65
# File 'lib/octopus/proxy.rb', line 63

def select_connection()
  @shards[shard_name].connection()
end

#shard_nameObject



67
68
69
# File 'lib/octopus/proxy.rb', line 67

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

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



77
78
79
80
81
82
83
84
85
86
87
88
89
# File 'lib/octopus/proxy.rb', line 77

def transaction(options = {}, &block)
  if should_send_queries_to_multiple_shards?
    self.send_transaction_to_multiple_shards(current_shard, options, &block)
  elsif should_send_queries_to_multiple_groups?
    self.send_transaction_to_multiple_groups(options, &block)
    @current_group = nil      
  elsif should_send_queries_to_a_group_of_shards?
    self.send_transaction_to_multiple_shards(@groups[current_group], options, &block)
    @current_group = nil      
  else
    select_connection.transaction(options, &block) 
  end
end