Module: Switchman::ActiveRecord::ConnectionPool

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

Instance Method Summary collapse

Instance Method Details

#checkout_new_connectionObject



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

def checkout_new_connection
  conn = synchronize do
    # ideally I would just keep a thread-local spec that I could modify
    # without locking anything, but if spec returns not-the-object passed
    # to initialize this pool, things break
    spec.config[:shard_name] = self.shard.name

    super
  end
  conn.shard = self.shard
  conn
end

#clear_idle_connections!(since_when) ⇒ Object



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

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

#connectionObject



35
36
37
38
39
40
# File 'lib/switchman/active_record/connection_pool.rb', line 35

def connection
  conn = super
  raise NonExistentShardError if shard.new_record?
  switch_database(conn) if conn.shard != self.shard
  conn
end

#default_schemaObject



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

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_id = Thread.current) ⇒ Object



42
43
44
45
46
47
48
# File 'lib/switchman/active_record/connection_pool.rb', line 42

def release_connection(with_id = Thread.current)
  super(with_id)

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

#shardObject



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

def shard
  Thread.current[tls_key] || Shard.default
end

#shard=(value) ⇒ Object



10
11
12
# File 'lib/switchman/active_record/connection_pool.rb', line 10

def shard=(value)
  Thread.current[tls_key] = value
end

#switch_database(conn) ⇒ Object



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

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