Class: Puma::ThreadPool

Inherits:
Object
  • Object
show all
Defined in:
lib/puma/thread_pool.rb

Overview

A simple thread pool management object.

Defined Under Namespace

Classes: AutoTrim

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(min, max, *extra, &block) ⇒ ThreadPool

Maintain a minimum of min and maximum of max threads in the pool.

The block passed is the work that will be performed in each thread.



14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
# File 'lib/puma/thread_pool.rb', line 14

def initialize(min, max, *extra, &block)
  @not_empty = ConditionVariable.new
  @not_full = ConditionVariable.new
  @mutex = Mutex.new

  @todo = []

  @spawned = 0
  @waiting = 0

  @min = Integer(min)
  @max = Integer(max)
  @block = block
  @extra = extra

  @shutdown = false

  @trim_requested = 0

  @workers = []

  @auto_trim = nil

  @mutex.synchronize do
    @min.times { spawn_thread }
  end

  @clean_thread_locals = false
end

Instance Attribute Details

#clean_thread_localsObject

Returns the value of attribute clean_thread_locals



45
46
47
# File 'lib/puma/thread_pool.rb', line 45

def clean_thread_locals
  @clean_thread_locals
end

#spawnedObject (readonly)

Returns the value of attribute spawned



44
45
46
# File 'lib/puma/thread_pool.rb', line 44

def spawned
  @spawned
end

#trim_requestedObject (readonly)

Returns the value of attribute trim_requested



44
45
46
# File 'lib/puma/thread_pool.rb', line 44

def trim_requested
  @trim_requested
end

Instance Method Details

#<<(work) ⇒ Object

Add work to the todo list for a Thread to pickup and process.



121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
# File 'lib/puma/thread_pool.rb', line 121

def <<(work)
  @mutex.synchronize do
    if @shutdown
      raise "Unable to add work while shutting down"
    end

    @todo << work

    if @waiting < @todo.size and @spawned < @max
      spawn_thread
    end

    @not_empty.signal
  end
end

#auto_trim!(timeout = 5) ⇒ Object



182
183
184
185
# File 'lib/puma/thread_pool.rb', line 182

def auto_trim!(timeout=5)
  @auto_trim = AutoTrim.new(self, timeout)
  @auto_trim.start!
end

#backlogObject

How many objects have yet to be processed by the pool?



49
50
51
# File 'lib/puma/thread_pool.rb', line 49

def backlog
  @mutex.synchronize { @todo.size }
end

#shutdownObject

Tell all threads in the pool to exit and wait for them to finish.



189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
# File 'lib/puma/thread_pool.rb', line 189

def shutdown
  @mutex.synchronize do
    @shutdown = true
    @not_empty.broadcast
    @not_full.broadcast

    @auto_trim.stop if @auto_trim
  end

  # Use this instead of #each so that we don't stop in the middle
  # of each and see a mutated object mid #each
  if !@workers.empty?
      @workers.first.join until @workers.empty?
  end

  @spawned = 0
  @workers = []
end

#trim(force = false) ⇒ Object

If too many threads are in the pool, tell one to finish go ahead and exit. If force is true, then a trim request is requested even if all threads are being utilized.



149
150
151
152
153
154
155
156
# File 'lib/puma/thread_pool.rb', line 149

def trim(force=false)
  @mutex.synchronize do
    if (force or @waiting > 0) and @spawned - @trim_requested > @min
      @trim_requested += 1
      @not_empty.signal
    end
  end
end

#wait_until_not_fullObject



137
138
139
140
141
142
143
# File 'lib/puma/thread_pool.rb', line 137

def wait_until_not_full
  @mutex.synchronize do
    until @todo.size - @waiting < @max - @spawned or @shutdown
      @not_full.wait @mutex
    end
  end
end