Class: ActiveRecord::Turntable::ConnectionProxy

Inherits:
Object
  • Object
show all
Includes:
Mixable
Defined in:
lib/active_record/turntable/connection_proxy.rb,
lib/active_record/turntable/connection_proxy/mixable.rb

Defined Under Namespace

Modules: Mixable

Constant Summary collapse

CLEAR_CACHE_METHODS =

for expiring query cache

[:update, :insert, :delete, :exec_insert, :exec_update, :exec_delete, :insert_many]

Constants included from Mixable

Mixable::EXCLUDE_QUERY_REGEXP, Mixable::METHODS_REGEXP, Mixable::QUERY_REGEXP

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from Mixable

#mixable?

Constructor Details

#initialize(klass, cluster, options = {}) ⇒ ConnectionProxy



12
13
14
15
16
17
18
# File 'lib/active_record/turntable/connection_proxy.rb', line 12

def initialize(klass, cluster, options = {})
  @klass   = klass
  @cluster = cluster
  @master_shard = MasterShard.new(klass)
  @default_current_shard = @master_shard
  @mixer = ActiveRecord::Turntable::Mixer.new(self)
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

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



56
57
58
59
60
61
62
63
64
65
66
67
68
69
# File 'lib/active_record/turntable/connection_proxy.rb', line 56

def method_missing(method, *args, &block)
  clear_query_cache_if_needed(method)
  if shard_fixed?
    connection.send(method, *args, &block)
  elsif mixable?(method, *args)
    fader = @mixer.build_fader(method, *args, &block)
    logger.debug { "[ActiveRecord::Turntable] Sending method: #{method}, " +
      "sql: #{args.first}, " +
      "shards: #{fader.shards_query_hash.keys.map(&:name)}" }
    fader.execute
  else
    connection.send(method, *args, &block)
  end
end

Instance Attribute Details

#klassObject (readonly)

Returns the value of attribute klass.



9
10
11
# File 'lib/active_record/turntable/connection_proxy.rb', line 9

def klass
  @klass
end

#specObject



232
233
234
# File 'lib/active_record/turntable/connection_proxy.rb', line 232

def spec
  @spec ||= master.connection_pool.spec
end

Instance Method Details

#cacheObject



33
34
35
36
37
38
# File 'lib/active_record/turntable/connection_proxy.rb', line 33

def cache
  enable_query_cache!
  yield
ensure
  clear_query_cache
end

#clear_query_cacheObject



50
51
52
53
54
# File 'lib/active_record/turntable/connection_proxy.rb', line 50

def clear_query_cache
  klass.turntable_connections.each do |k,v|
    v.connection.clear_query_cache
  end
end

#clear_query_cache_if_needed(method) ⇒ Object



46
47
48
# File 'lib/active_record/turntable/connection_proxy.rb', line 46

def clear_query_cache_if_needed(method)
  clear_query_cache if CLEAR_CACHE_METHODS.include?(method)
end

#clusterObject



75
76
77
# File 'lib/active_record/turntable/connection_proxy.rb', line 75

def cluster
  @cluster
end

#columns(*args) ⇒ Object



212
213
214
215
216
217
218
# File 'lib/active_record/turntable/connection_proxy.rb', line 212

def columns(*args)
  if args.size > 0
    master.connection_pool.columns[*args]
  else
    master.connection_pool.columns
  end
end

#connectionObject



117
118
119
# File 'lib/active_record/turntable/connection_proxy.rb', line 117

def connection
  current_shard.connection
end

#connection_poolObject



122
123
124
# File 'lib/active_record/turntable/connection_proxy.rb', line 122

def connection_pool
  current_shard.connection_pool
end

#current_shardObject



107
108
109
# File 'lib/active_record/turntable/connection_proxy.rb', line 107

def current_shard
  current_shard_entry[object_id] ||= @default_current_shard
end

#current_shard=(shard) ⇒ Object



111
112
113
114
# File 'lib/active_record/turntable/connection_proxy.rb', line 111

def current_shard=(shard)
  logger.debug { "Changing #{klass}'s shard to #{shard.name}"}
  current_shard_entry[object_id] = shard
end

#enable_query_cache!Object



40
41
42
43
44
# File 'lib/active_record/turntable/connection_proxy.rb', line 40

def enable_query_cache!
  klass.turntable_connections.each do |k,v|
    v.connection.enable_query_cache!
  end
end

#fixed_shardObject



87
88
89
# File 'lib/active_record/turntable/connection_proxy.rb', line 87

def fixed_shard
  fixed_shard_entry[object_id]
end

#fixed_shard=(shard) ⇒ Object



91
92
93
# File 'lib/active_record/turntable/connection_proxy.rb', line 91

def fixed_shard=(shard)
  fixed_shard_entry[object_id] = shard
end

#masterObject



95
96
97
# File 'lib/active_record/turntable/connection_proxy.rb', line 95

def master
  @master_shard
end

#master_connectionObject



99
100
101
# File 'lib/active_record/turntable/connection_proxy.rb', line 99

def master_connection
  master.connection
end

#pk_and_sequence_for(*args) ⇒ Object



220
221
222
# File 'lib/active_record/turntable/connection_proxy.rb', line 220

def pk_and_sequence_for(*args)
  master.connection.send(:pk_and_sequence_for, *args)
end

#primary_key(*args) ⇒ Object



224
225
226
# File 'lib/active_record/turntable/connection_proxy.rb', line 224

def primary_key(*args)
  master.connection.send(:primary_key, *args)
end

#seqObject



103
104
105
# File 'lib/active_record/turntable/connection_proxy.rb', line 103

def seq
  @cluster.seq || master
end

#shard_fixed?Boolean



83
84
85
# File 'lib/active_record/turntable/connection_proxy.rb', line 83

def shard_fixed?
  !!fixed_shard
end

#shardsObject



79
80
81
# File 'lib/active_record/turntable/connection_proxy.rb', line 79

def shards
  @cluster.shards
end

#supports_views?(*args) ⇒ Boolean



228
229
230
# File 'lib/active_record/turntable/connection_proxy.rb', line 228

def supports_views?(*args)
  master.connection.send(:supports_views?, *args)
end

#to_sql(arel, binds = []) ⇒ Object



71
72
73
# File 'lib/active_record/turntable/connection_proxy.rb', line 71

def to_sql(arel, binds = [])
  master.connection.to_sql(arel, binds)
end

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



29
30
31
# File 'lib/active_record/turntable/connection_proxy.rb', line 29

def transaction(options = {}, &block)
  connection.transaction(options, &block)
end

#with_all(continue_on_error = false) ⇒ Object

Send queries to all shards in this cluster



157
158
159
160
161
162
163
164
165
166
167
168
169
170
# File 'lib/active_record/turntable/connection_proxy.rb', line 157

def with_all(continue_on_error = false)
  @cluster.shards.values.map do |shard|
    begin
      with_shard(shard) {
        yield
      }
    rescue Exception => err
      unless continue_on_error
        raise err
      end
      err
    end
  end
end

#with_master(&block) ⇒ Object



189
190
191
192
193
# File 'lib/active_record/turntable/connection_proxy.rb', line 189

def with_master(&block)
  with_shard(master) do
    yield
  end
end

#with_master_and_all(continue_on_error = false) ⇒ Object

Send queries to master connection and all shards in this cluster



174
175
176
177
178
179
180
181
182
183
184
185
186
187
# File 'lib/active_record/turntable/connection_proxy.rb', line 174

def with_master_and_all(continue_on_error = false)
  ([master] + @cluster.shards.values).map do |shard|
    begin
      with_shard(shard) {
        yield
      }
    rescue Exception => err
      unless continue_on_error
        raise err
      end
      err
    end
  end
end

#with_recursive_shards(connection_name, *klasses, &block) ⇒ Object



144
145
146
147
148
149
150
151
152
153
# File 'lib/active_record/turntable/connection_proxy.rb', line 144

def with_recursive_shards(connection_name, *klasses, &block)
  with_shard(shards[connection_name]) do
    if klasses.blank?
      yield
    else
      current_klass = klasses.shift
      current_klass.connection.with_recursive_shards(connection_name, *klasses, &block)
    end
  end
end

#with_shard(shard) ⇒ Object

Fix connection to given shard in block



132
133
134
135
136
137
138
139
140
141
142
# File 'lib/active_record/turntable/connection_proxy.rb', line 132

def with_shard(shard)
  shard = cluster.to_shard(shard)

  old_shard, old_fixed = current_shard, fixed_shard
  self.current_shard = shard
  self.fixed_shard = shard
  yield
ensure
  self.fixed_shard = old_fixed
  self.current_shard = old_shard
end