Class: Rooq::Adapters::PostgreSQL::ConnectionPool

Inherits:
ConnectionPool show all
Defined in:
lib/rooq/adapters/postgresql.rb

Overview

A simple connection pool for PostgreSQL connections. For production use, consider using a more robust pool like connection_pool gem.

Examples:

Basic usage

pool = Rooq::Adapters::PostgreSQL::ConnectionPool.new(size: 5) do
  PG.connect(dbname: 'myapp', host: 'localhost')
end

ctx = Rooq::Context.using_pool(pool)
# ... execute queries ...
pool.shutdown

With timeout

pool = Rooq::Adapters::PostgreSQL::ConnectionPool.new(size: 10, timeout: 5) do
  PG.connect(connection_string)
end

Defined Under Namespace

Classes: TimeoutError

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(size: 5, timeout: nil) { ... } ⇒ ConnectionPool

Create a new connection pool.

Parameters:

  • size (Integer) (defaults to: 5)

    the maximum number of connections

  • timeout (Numeric) (defaults to: nil)

    seconds to wait for a connection (nil = wait forever)

Yields:

  • the block that creates a new connection



31
32
33
34
35
36
37
38
39
40
41
42
43
44
# File 'lib/rooq/adapters/postgresql.rb', line 31

def initialize(size: 5, timeout: nil, &block)
  super()
  @size = size
  @timeout = timeout
  @create_connection = block
  @mutex = Mutex.new
  @condition = ConditionVariable.new
  @available = []
  @in_use = []
  @shutdown = false

  # Pre-create all connections
  @size.times { @available << @create_connection.call }
end

Instance Attribute Details

#sizeObject (readonly)

Returns the value of attribute size.



25
26
27
# File 'lib/rooq/adapters/postgresql.rb', line 25

def size
  @size
end

Instance Method Details

#availableInteger

Returns number of available connections.

Returns:

  • (Integer)

    number of available connections



85
86
87
# File 'lib/rooq/adapters/postgresql.rb', line 85

def available
  @mutex.synchronize { @available.length }
end

#checkin(connection) ⇒ Object

Check in a connection back to the pool.

Parameters:

  • connection (PG::Connection)

    the connection to return



76
77
78
79
80
81
82
# File 'lib/rooq/adapters/postgresql.rb', line 76

def checkin(connection)
  @mutex.synchronize do
    @in_use.delete(connection)
    @available << connection unless @shutdown
    @condition.signal
  end
end

#checkoutPG::Connection

Check out a connection from the pool.

Returns:

  • (PG::Connection)

    a database connection

Raises:



49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
# File 'lib/rooq/adapters/postgresql.rb', line 49

def checkout
  @mutex.synchronize do
    raise Error, "Pool has been shut down" if @shutdown

    deadline = @timeout ? Time.now + @timeout : nil

    while @available.empty?
      if deadline
        remaining = deadline - Time.now
        raise TimeoutError, "Timed out waiting for connection" if remaining <= 0

        @condition.wait(@mutex, remaining)
      else
        @condition.wait(@mutex)
      end

      raise Error, "Pool has been shut down" if @shutdown
    end

    connection = @available.pop
    @in_use << connection
    connection
  end
end

#shutdownObject

Shutdown the pool and close all connections.



90
91
92
93
94
95
96
97
98
99
# File 'lib/rooq/adapters/postgresql.rb', line 90

def shutdown
  @mutex.synchronize do
    @shutdown = true
    @available.each { |conn| conn.close if conn.respond_to?(:close) }
    @in_use.each { |conn| conn.close if conn.respond_to?(:close) }
    @available.clear
    @in_use.clear
    @condition.broadcast
  end
end