Module: Switchman::ActiveRecord::ConnectionPool

Defined in:
lib/switchman/active_record/connection_pool.rb

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#shardObject



12
13
14
# File 'lib/switchman/active_record/connection_pool.rb', line 12

def shard
  @shard || Shard.default
end

Class Method Details

.included(klass) ⇒ Object



4
5
6
7
8
# File 'lib/switchman/active_record/connection_pool.rb', line 4

def self.included(klass)
  klass.alias_method_chain(:checkout_new_connection, :sharding)
  klass.alias_method_chain(:connection, :sharding)
  klass.alias_method_chain(:release_connection, :idle_timeout)
end

Instance Method Details

#checkout_new_connection_with_shardingObject



24
25
26
27
28
29
30
31
# File 'lib/switchman/active_record/connection_pool.rb', line 24

def checkout_new_connection_with_sharding
  # TODO: this might be a threading issue
  spec.config[:shard_name] = self.shard.name

  conn = checkout_new_connection_without_sharding
  conn.shard = self.shard
  conn
end

#clear_idle_connections!(since_when) ⇒ Object



55
56
57
58
59
60
61
62
63
64
# File 'lib/switchman/active_record/connection_pool.rb', line 55

def clear_idle_connections!(since_when)
  @connections.reject! do |conn|
    if conn.last_query_at < since_when && !conn.in_use?
      conn.disconnect!
      true
    else
      false
    end
  end
end

#connection_with_shardingObject



33
34
35
36
37
# File 'lib/switchman/active_record/connection_pool.rb', line 33

def connection_with_sharding
  conn = connection_without_sharding
  switch_database(conn) if conn.shard != self.shard
  conn
end

#default_schemaObject



16
17
18
19
20
21
22
# File 'lib/switchman/active_record/connection_pool.rb', line 16

def default_schema
  raise "Not postgres!" unless self.spec.config[:adapter] == 'postgresql'
  connection unless @schemas
  # default shard will not switch databases immediately, so it won't be set yet
  @schemas ||= connection.schemas
  @schemas.first
end

#release_connection_with_idle_timeout(*args) ⇒ Object



39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
# File 'lib/switchman/active_record/connection_pool.rb', line 39

def release_connection_with_idle_timeout(*args)
  if ::Rails.version < '4'
    raise ArgumentError, "wrong number of arguments (1 for 0)" unless args.empty?
    release_connection_without_idle_timeout
  else
    release_connection_without_idle_timeout(*args)
  end

  # TODO may need a synchronize (or to be included in a synchronize
  # inside release_connection_without_idle_timeout) when we make
  # switchman thread-safe
  if spec.config[:idle_timeout]
    clear_idle_connections!(Time.now - spec.config[:idle_timeout].to_i)
  end
end

#switch_database(conn) ⇒ Object



66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
# File 'lib/switchman/active_record/connection_pool.rb', line 66

def switch_database(conn)
  if !@schemas && conn.adapter_name == 'PostgreSQL' && !self.shard.database_server.config[:shard_name]
    @schemas = conn.schemas
  end

  spec.config[:shard_name] = self.shard.name
  case conn.adapter_name
    when 'MySQL', 'Mysql2'
      conn.execute("USE #{spec.config[:database]}")
    when 'PostgreSQL'
      conn.schema_search_path = spec.config[:schema_search_path]
    when 'SQLite'
      # This is an artifact of the adapter modifying the path to be an absolute path when it is instantiated; just let it slide
    else
      raise("Cannot switch databases on same DatabaseServer with adapter type: #{conn.adapter_name}. Limit one Shard per DatabaseServer.")
  end
  conn.shard = shard
end