Class: Philiprehberger::HttpClient::Pool

Inherits:
Object
  • Object
show all
Defined in:
lib/philiprehberger/http_client/pool.rb

Overview

Thread-safe connection pool that reuses Net::HTTP connections to the same host:port. Idle connections are automatically expired after the configured timeout.

Examples:

pool = Pool.new(size: 5, idle_timeout: 60)
conn = pool.checkout(uri)
# ... use conn ...
pool.checkin(uri, conn)

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(size: 5, idle_timeout: 60) ⇒ Pool

Returns a new instance of Pool.

Parameters:

  • size (Integer) (defaults to: 5)

    maximum number of connections per host:port

  • idle_timeout (Integer) (defaults to: 60)

    seconds before an idle connection is expired



18
19
20
21
22
23
# File 'lib/philiprehberger/http_client/pool.rb', line 18

def initialize(size: 5, idle_timeout: 60)
  @size = size
  @idle_timeout = idle_timeout
  @monitor = Monitor.new
  @pools = {}
end

Instance Attribute Details

#idle_timeoutInteger (readonly)

Returns the idle timeout in seconds.

Returns:

  • (Integer)


33
34
35
# File 'lib/philiprehberger/http_client/pool.rb', line 33

def idle_timeout
  @idle_timeout
end

#sizeInteger (readonly)

Returns the maximum pool size.

Returns:

  • (Integer)


28
29
30
# File 'lib/philiprehberger/http_client/pool.rb', line 28

def size
  @size
end

Instance Method Details

#checkin(uri, connection) ⇒ void

This method returns an undefined value.

Return a connection to the pool for reuse.

Parameters:

  • uri (URI)

    the request URI

  • connection (Net::HTTP)

    the connection to return



57
58
59
60
61
62
63
64
65
66
67
68
69
# File 'lib/philiprehberger/http_client/pool.rb', line 57

def checkin(uri, connection)
  key = pool_key(uri)
  @monitor.synchronize do
    entries = @pools[key] ||= []
    purge_expired(entries)

    if entries.size < @size
      entries.push({ connection: connection, checked_in_at: now })
    else
      safe_finish(connection)
    end
  end
end

#checkout(uri) ⇒ Net::HTTP?

Check out a connection for the given URI’s host:port. Returns an existing idle connection if available, or nil if none are available.

Parameters:

  • uri (URI)

    the request URI

Returns:

  • (Net::HTTP, nil)

    a reusable connection or nil



40
41
42
43
44
45
46
47
48
49
50
# File 'lib/philiprehberger/http_client/pool.rb', line 40

def checkout(uri)
  key = pool_key(uri)
  @monitor.synchronize do
    entries = @pools[key] || []
    purge_expired(entries)
    @pools[key] = entries

    entry = entries.shift
    entry&.fetch(:connection)
  end
end

#drainvoid

This method returns an undefined value.

Close all pooled connections and clear the pool.



74
75
76
77
78
79
80
81
# File 'lib/philiprehberger/http_client/pool.rb', line 74

def drain
  @monitor.synchronize do
    @pools.each_value do |entries|
      entries.each { |entry| safe_finish(entry[:connection]) }
    end
    @pools.clear
  end
end

#idle_countInteger

Return the number of idle connections across all hosts.

Returns:

  • (Integer)


86
87
88
89
90
# File 'lib/philiprehberger/http_client/pool.rb', line 86

def idle_count
  @monitor.synchronize do
    @pools.values.sum(&:size)
  end
end