Class: SugarCRM::ConnectionPool

Inherits:
Object
  • Object
show all
Defined in:
lib/sugarcrm/connection_pool.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(session) ⇒ ConnectionPool

Returns a new instance of ConnectionPool.



6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# File 'lib/sugarcrm/connection_pool.rb', line 6

def initialize(session)
  @session = session
  
  # The cache of reserved connections mapped to threads
  @reserved_connections = {}
  
  # The mutex used to synchronize pool access
  @connection_mutex = Monitor.new
  @queue = @connection_mutex.new_cond
  @timeout = config_timeout || 10
  
  # default max pool size to 5
  @size = config_pool_size || default_pool_size
  
  @connections = []
  @checked_out = []
end

Instance Attribute Details

#sizeObject (readonly)

Returns the value of attribute size.



5
6
7
# File 'lib/sugarcrm/connection_pool.rb', line 5

def size
  @size
end

#timeoutObject

Returns the value of attribute timeout.



4
5
6
# File 'lib/sugarcrm/connection_pool.rb', line 4

def timeout
  @timeout
end

Instance Method Details

#checkin(conn) ⇒ Object

Check-in a sugarcrm connection back into the pool, indicating that you no longer need this connection.



82
83
84
85
86
87
# File 'lib/sugarcrm/connection_pool.rb', line 82

def checkin(conn)
  @connection_mutex.synchronize do
    @checked_out.delete conn
    @queue.signal
  end
end

#checkoutObject

Check-out a sugarcrm connection from the pool, indicating that you want to use it. You should call #checkin when you no longer need this.

This is done by either returning an existing connection, or by creating a new connection. If the maximum number of connections for this pool has already been reached, but the pool is empty (i.e. they’re all being used), then this method will wait until a thread has checked in a connection. The wait time is bounded however: if no connection can be checked out within the timeout specified for this pool, then a ConnectionTimeoutError exception will be raised.



54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
# File 'lib/sugarcrm/connection_pool.rb', line 54

def checkout
  # Checkout an available connection
  @connection_mutex.synchronize do
    loop do
      conn = if @checked_out.size < @connections.size
                checkout_existing_connection
              elsif @connections.size < @size
                checkout_new_connection
              end
      return conn if conn

      @queue.wait(@timeout)

      if(@checked_out.size < @connections.size)
        next
      else
        clear_stale_cached_connections!
        if @size == @checked_out.size
          raise SugarCRM::ConnectionTimeoutError, "could not obtain a sugarcrm connection#{" within #{@timeout} seconds" if @timeout}. The max pool size is currently #{@size}; consider increasing it."
        end
      end

    end
  end
end

#clear_stale_cached_connections!Object

Return any checked-out connections back to the pool by threads that are no longer alive.



103
104
105
106
107
108
109
110
111
# File 'lib/sugarcrm/connection_pool.rb', line 103

def clear_stale_cached_connections!
  keys = @reserved_connections.keys - Thread.list.find_all { |t|
    t.alive?
  }.map { |thread| thread.object_id }
  keys.each do |key|
    checkin @reserved_connections[key]
    @reserved_connections.delete(key)
  end
end

#connectionObject

Retrieve the connection associated with the current thread, or call #checkout to obtain one if necessary.

#connection can be called any number of times; the connection is held in a hash keyed by the thread id.



40
41
42
# File 'lib/sugarcrm/connection_pool.rb', line 40

def connection
  @reserved_connections[current_connection_id] ||= checkout
end

#disconnect!Object

Disconnects all connections in the pool, and clears the pool.



90
91
92
93
94
95
96
97
98
99
# File 'lib/sugarcrm/connection_pool.rb', line 90

def disconnect!
  @reserved_connections.each_value do |conn|
    checkin conn
  end
  @reserved_connections = {}
  @connections.each do |conn|
    conn.logout
  end
  @connections = []
end

#with_connectionObject

If a connection already exists yield it to the block. If no connection exists checkout a connection, yield it to the block, and checkin the connection when finished.



27
28
29
30
31
32
33
# File 'lib/sugarcrm/connection_pool.rb', line 27

def with_connection
  connection_id = current_connection_id
  fresh_connection = true unless @reserved_connections[connection_id]
  yield connection
ensure
  release_connection(connection_id) if fresh_connection
end