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



47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
# File 'lib/switchman/active_record/connection_pool.rb', line 47

def clear_idle_connections!(since_when)
  synchronize do
    @connections.reject! do |conn|
      if conn.last_query_at < since_when && !conn.in_use?
        conn.disconnect!
        true
      else
        false
      end
    end
    @available.clear
    @connections.each do |conn|
      @available.add conn
    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.current_schemas
  @schemas.first
end

#release_connection_with_idle_timeout(with_id = current_connection_id) ⇒ Object



39
40
41
42
43
44
45
# File 'lib/switchman/active_record/connection_pool.rb', line 39

def release_connection_with_idle_timeout(with_id = current_connection_id)
  release_connection_without_idle_timeout(with_id)

  if spec.config[:idle_timeout]
    clear_idle_connections!(Time.now - spec.config[:idle_timeout].to_i)
  end
end

#switch_database(conn) ⇒ Object



64
65
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 64

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

  spec.config[:shard_name] = self.shard.name
  case conn.adapter_name
    when 'MySQL', 'Mysql2'
      conn.execute("USE #{spec.config[:database]}")
    when 'PostgreSQL'
      if conn.schema_search_path != spec.config[:schema_search_path]
        conn.schema_search_path = spec.config[:schema_search_path]
      end
    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