Class: Pod4::ConnectionPool

Inherits:
Connection show all
Defined in:
lib/pod4/connection_pool.rb

Defined Under Namespace

Classes: Pool, PoolItem

Constant Summary collapse

DEFAULT_MAX_CLIENTS =
10

Instance Attribute Summary collapse

Attributes inherited from Connection

#data_layer_options, #interface_class

Instance Method Summary collapse

Constructor Details

#initialize(args) ⇒ ConnectionPool

As Connection, but with some options you can set.

  • max_clients – if this many clients are assigned to threads, wait until one is freed.

pass nil for no maximum. Tries to default to something sensible.

  • max_wait – throw a Pod4::PoolTimeout if you wait more than this time in seconds.

Pass nil to wait forever. Default is nil, because you would need to handle that timeout.



73
74
75
76
77
78
79
# File 'lib/pod4/connection_pool.rb', line 73

def initialize(args)
  super(args)

  @max_clients = args[:max_clients] || DEFAULT_MAX_CLIENTS
  @max_wait    = args[:max_wait]
  @pool        = Pool.new
end

Instance Attribute Details

#max_clientsObject (readonly)

of Pool



60
61
62
# File 'lib/pod4/connection_pool.rb', line 60

def max_clients
  @max_clients
end

#max_waitObject (readonly)

of Pool



60
61
62
# File 'lib/pod4/connection_pool.rb', line 60

def max_wait
  @max_wait
end

Instance Method Details

#_poolObject

Dump the internal pool (for test purposes only)



146
147
148
# File 'lib/pod4/connection_pool.rb', line 146

def _pool
  @pool._dump
end

#client(interface) ⇒ Object

Return a client for the interface to use.

Return the client we gave this thread before. Failing that, assign a free one from the pool. Failing that, ask the interface to give us a new client.

Note: The interface passes itself in case we want to call it back to get a new client; but clients are assigned to a thread. Every interface in a given thread gets the same pool item, the same client object.



92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
# File 'lib/pod4/connection_pool.rb', line 92

def client(interface)
  time = Time.now
  cl   = nil

  # NB: We are constrained to use loop in order for our test to work
  loop do
    if (pi = @pool.get_current)
      cl = pi.client
      break
    end

    if (pi = @pool.get_free)
      cl = pi.client
      break
    end

    if @max_clients && @pool.size >= @max_clients 
      raise Pod4::PoolTimeout if @max_wait && (Time.now - time > @max_wait)
      sleep 1
      next
    end

    cl = interface.new_connection(@data_layer_options)
    @pool << cl
    break
  end # of loop

  cl
end

#close(interface) ⇒ Object

De-assign the client for the current thread from that thread.

We never ask the interface to close the connection to the database. There is no advantage in doing that for us.

Note: The interface passes itself in case we want to call it back to actually close the client; but clients are assigned to a thread.



131
132
133
# File 'lib/pod4/connection_pool.rb', line 131

def close(interface)
  @pool.release
end

#drop(interface) ⇒ Object

Remove the client object entirely – for example, because the connection to the database has expired.



139
140
141
# File 'lib/pod4/connection_pool.rb', line 139

def drop(interface)
  @pool.drop
end