Class: Bundler::ConnectionPool::TimedStack

Inherits:
Object
  • Object
show all
Defined in:
lib/bundler/vendor/connection_pool/lib/connection_pool/timed_stack.rb

Overview

The TimedStack manages a pool of homogeneous connections (or any resource you wish to manage). Connections are created lazily up to a given maximum number.

Examples:

ts = TimedStack.new(1) { MyConnection.new }

# fetch a connection
conn = ts.pop

# return a connection
ts.push conn

conn = ts.pop
ts.pop timeout: 5
#=> raises Bundler::ConnectionPool::TimeoutError after 5 seconds

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(size = 0, &block) ⇒ TimedStack

Creates a new pool with size connections that are created from the given block.



25
26
27
28
29
30
31
32
33
# File 'lib/bundler/vendor/connection_pool/lib/connection_pool/timed_stack.rb', line 25

def initialize(size = 0, &block)
  @create_block = block
  @created = 0
  @que = []
  @max = size
  @mutex = Thread::Mutex.new
  @resource = Thread::ConditionVariable.new
  @shutdown_block = nil
end

Instance Attribute Details

#maxObject (readonly)

Returns the value of attribute max.



20
21
22
# File 'lib/bundler/vendor/connection_pool/lib/connection_pool/timed_stack.rb', line 20

def max
  @max
end

Instance Method Details

#decrement_createdObject

Reduce the created count



139
140
141
# File 'lib/bundler/vendor/connection_pool/lib/connection_pool/timed_stack.rb', line 139

def decrement_created
  @created -= 1 unless @created == 0
end

#empty?Boolean

Returns true if there are no available connections.

Returns:

  • (Boolean)


121
122
123
# File 'lib/bundler/vendor/connection_pool/lib/connection_pool/timed_stack.rb', line 121

def empty?
  (@created - @que.length) >= @max
end

#idleObject

The number of connections created and available on the stack.



133
134
135
# File 'lib/bundler/vendor/connection_pool/lib/connection_pool/timed_stack.rb', line 133

def idle
  @que.length
end

#lengthObject

The number of connections available on the stack.



127
128
129
# File 'lib/bundler/vendor/connection_pool/lib/connection_pool/timed_stack.rb', line 127

def length
  @max - @created + @que.length
end

#pop(timeout = 0.5, options = {}) ⇒ Object

Retrieves a connection from the stack. If a connection is available it is immediately returned. If no connection is available within the given timeout a Bundler::ConnectionPool::TimeoutError is raised.

:timeout is the only checked entry in options and is preferred over the timeout argument (which will be removed in a future release). Other options may be used by subclasses that extend TimedStack.



60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
# File 'lib/bundler/vendor/connection_pool/lib/connection_pool/timed_stack.rb', line 60

def pop(timeout = 0.5, options = {})
  options, timeout = timeout, 0.5 if Hash === timeout
  timeout = options.fetch :timeout, timeout

  deadline = current_time + timeout
  @mutex.synchronize do
    loop do
      raise Bundler::ConnectionPool::PoolShuttingDownError if @shutdown_block
      if (conn = try_fetch_connection(options))
        return conn
      end

      connection = try_create(options)
      return connection if connection

      to_wait = deadline - current_time
      raise Bundler::ConnectionPool::TimeoutError, "Waited #{timeout} sec, #{length}/#{@max} available" if to_wait <= 0
      @resource.wait(@mutex, to_wait)
    end
  end
end

#push(obj, options = {}) ⇒ Object Also known as: <<

Returns obj to the stack. options is ignored in TimedStack but may be used by subclasses that extend TimedStack.



38
39
40
41
42
43
44
45
46
47
48
49
# File 'lib/bundler/vendor/connection_pool/lib/connection_pool/timed_stack.rb', line 38

def push(obj, options = {})
  @mutex.synchronize do
    if @shutdown_block
      @created -= 1 unless @created == 0
      @shutdown_block.call(obj)
    else
      store_connection obj, options
    end

    @resource.broadcast
  end
end

#reap(idle_seconds, &block) ⇒ Object

Reaps connections that were checked in more than idle_seconds ago.

Raises:

  • (ArgumentError)


101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
# File 'lib/bundler/vendor/connection_pool/lib/connection_pool/timed_stack.rb', line 101

def reap(idle_seconds, &block)
  raise ArgumentError, "reap must receive a block" unless block
  raise ArgumentError, "idle_seconds must be a number" unless idle_seconds.is_a?(Numeric)
  raise Bundler::ConnectionPool::PoolShuttingDownError if @shutdown_block

  idle.times do
    conn =
      @mutex.synchronize do
        raise Bundler::ConnectionPool::PoolShuttingDownError if @shutdown_block

        reserve_idle_connection(idle_seconds)
      end
    break unless conn

    block.call(conn)
  end
end

#shutdown(reload: false, &block) ⇒ Object

Shuts down the TimedStack by passing each connection to block and then removing it from the pool. Attempting to checkout a connection after shutdown will raise Bundler::ConnectionPool::PoolShuttingDownError unless :reload is true.

Raises:

  • (ArgumentError)


87
88
89
90
91
92
93
94
95
96
97
# File 'lib/bundler/vendor/connection_pool/lib/connection_pool/timed_stack.rb', line 87

def shutdown(reload: false, &block)
  raise ArgumentError, "shutdown must receive a block" unless block

  @mutex.synchronize do
    @shutdown_block = block
    @resource.broadcast

    shutdown_connections
    @shutdown_block = nil if reload
  end
end