Module: Switchman::ActiveRecord::ConnectionPool

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

Instance Method Summary collapse

Instance Method Details

#checkout_new_connectionObject



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

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



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

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(switch_shard: true) ⇒ Object



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

def connection(switch_shard: true)
  conn = super()
  raise NonExistentShardError if shard.new_record?
  switch_database(conn) if conn.shard != self.shard && switch_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_id = Thread.current) ⇒ Object



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

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

#remove_shard!(shard) ⇒ Object



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

def remove_shard!(shard)
  synchronize do
    # The shard might be currently active, so we need to update our own shard
    if self.shard == shard
      self.shard = Shard.default
    end
    # Update out any connections that may be using this shard
    @connections.each do |conn|
      # This will also update the connection's shard to the default shard
      switch_database(conn) if conn.shard == shard
    end
  end
end

#shardObject



8
9
10
# File 'lib/switchman/active_record/connection_pool.rb', line 8

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

#shard=(value) ⇒ Object



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

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

#switch_database(conn) ⇒ Object



83
84
85
86
87
88
89
90
# File 'lib/switchman/active_record/connection_pool.rb', line 83

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
  conn.shard = shard
end