Class: ActiveReplicas::ProxyingConnectionPool

Inherits:
Object
  • Object
show all
Defined in:
lib/active_replicas/proxying_connection_pool.rb

Overview

Manages connection pools to the primary and replica databases. Returns proxy connection instances from those pools on request.

Also hanldes the internal state of switching back and forth from replica to primary connections based on heuristics or overrides.

NOTE: This proxy instance should be provisioned per-thread and it is not

thread-safe!

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(handler) ⇒ ProxyingConnectionPool

handler - ProcessLocalConnectionHandler which created this pool.



18
19
20
21
22
23
24
25
# File 'lib/active_replicas/proxying_connection_pool.rb', line 18

def initialize(handler)
  @handler = handler

  # Calls to `with_primary` will increment and decrement this.
  @primary_depth = 0
  # Current connection pool.
  @current_pool = nil
end

Instance Attribute Details

#handlerObject (readonly)

Returns the value of attribute handler.



15
16
17
# File 'lib/active_replicas/proxying_connection_pool.rb', line 15

def handler
  @handler
end

Instance Method Details

#active_connection?Boolean

Returns:

  • (Boolean)


43
44
45
# File 'lib/active_replicas/proxying_connection_pool.rb', line 43

def active_connection?
  all_pools.any?(&:active_connection?)
end

#all_poolsObject

Returns an Enumerable over all the pools, primary and replicas, used by this proxying pool.



131
132
133
# File 'lib/active_replicas/proxying_connection_pool.rb', line 131

def all_pools
  [primary_pool] + replica_pools.values
end

#automatic_reconnect=(new_value) ⇒ Object

ConnectionPool attribute readers and accessors



81
82
83
84
85
# File 'lib/active_replicas/proxying_connection_pool.rb', line 81

def automatic_reconnect=(new_value)
  all_pools.each do |pool|
    pool.automatic_reconnect = new_value
  end
end

#clear_reloadable_connections!Object



66
67
68
# File 'lib/active_replicas/proxying_connection_pool.rb', line 66

def clear_reloadable_connections!
  all_pools.each(&:clear_reloadable_connections!)
end

#connected?Boolean

Returns:

  • (Boolean)


58
59
60
# File 'lib/active_replicas/proxying_connection_pool.rb', line 58

def connected?
  current_pool.connected?
end

#connectionObject

ConnectionPool interface methods



32
33
34
35
36
37
38
39
40
41
# File 'lib/active_replicas/proxying_connection_pool.rb', line 32

def connection
  pool = current_pool

  conn = pool.connection
  return unless conn

  ProxyingConnection.new connection: conn,
                         is_primary: pool == primary_pool,
                         proxy:      self
end

#connectionsObject



87
88
89
# File 'lib/active_replicas/proxying_connection_pool.rb', line 87

def connections
  primary_pool.connections
end

#current_poolObject



70
71
72
73
74
75
76
# File 'lib/active_replicas/proxying_connection_pool.rb', line 70

def current_pool
  if @current_pool == nil
    @current_pool = next_pool
  end

  @current_pool
end

#disconnect!Object



62
63
64
# File 'lib/active_replicas/proxying_connection_pool.rb', line 62

def disconnect!
  all_pools.each(&:disconnect!)
end

#pool_which_owns_connection(object_id) ⇒ Object



135
136
137
138
139
140
141
142
143
# File 'lib/active_replicas/proxying_connection_pool.rb', line 135

def pool_which_owns_connection(object_id)
  return primary_pool if primary_pool.connections.any? { |c| c.object_id == object_id }

  replica_pools.values.each do |pool|
    return pool if pool.connections.any? { |c| c.object_id == object_id }
  end

  nil
end

#primary_connectionObject

Quick accessor to a primary connection.

NOTE: If this is not already in a with_primary block then calling this

will irreversably place the proxying pool in the primary state until
`release_connection!` is called! If you want to *temporarily*
use the primary then explicitly do so using `with_primary`.


120
121
122
123
124
125
126
127
# File 'lib/active_replicas/proxying_connection_pool.rb', line 120

def primary_connection
  if @primary_depth == 0
    @primary_depth += 1
    @current_pool = primary_pool
  end

  connection
end

#primary_pool?(pool) ⇒ Boolean

Returns:

  • (Boolean)


145
146
147
# File 'lib/active_replicas/proxying_connection_pool.rb', line 145

def primary_pool?(pool)
  pool == primary_pool
end

#release_connectionObject



47
48
49
50
51
52
# File 'lib/active_replicas/proxying_connection_pool.rb', line 47

def release_connection
  all_pools.each(&:release_connection)

  @primary_depth = 0
  @current_pool = nil
end

#replica_pool?(pool) ⇒ Boolean

Returns:

  • (Boolean)


149
150
151
# File 'lib/active_replicas/proxying_connection_pool.rb', line 149

def replica_pool?(pool)
  replica_pools.values.include? pool
end

#specObject



91
92
93
# File 'lib/active_replicas/proxying_connection_pool.rb', line 91

def spec
  primary_pool.spec
end

#using_primary?Boolean

Returns:

  • (Boolean)


110
111
112
# File 'lib/active_replicas/proxying_connection_pool.rb', line 110

def using_primary?
  @primary_depth > 0
end

#with_connection(&block) ⇒ Object



54
55
56
# File 'lib/active_replicas/proxying_connection_pool.rb', line 54

def with_connection(&block)
  current_pool.with_connection(&block)
end

#with_primaryObject

Additional methods



98
99
100
101
102
103
104
105
106
107
108
# File 'lib/active_replicas/proxying_connection_pool.rb', line 98

def with_primary
  previous_pool = @current_pool

  @primary_depth += 1
  @current_pool = primary_pool

  yield connection
ensure
  @primary_depth = [@primary_depth - 1, 0].max
  @current_pool = previous_pool
end