threadpool 0.0.1 → 0.0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (4) hide show
  1. data/README.md +15 -1
  2. data/lib/threadpool.rb +19 -16
  3. data/threadpool.gemspec +1 -1
  4. metadata +1 -1
data/README.md CHANGED
@@ -4,8 +4,22 @@ All the implementations I looked at were either buggy or wasted CPU resources
4
4
  for no apparent reason, for example used a sleep of 0.01 seconds to then check for
5
5
  readiness and stuff like this.
6
6
 
7
- This implementation uses `IO.select` instead, there is no timed sleep, it just only stays
7
+ This implementation uses `IO.select` instead, there is no timed sleep, it just stays
8
8
  there waiting for input, which will then come from a `#wake_up` call that writes on a pipe.
9
9
 
10
10
  `IO.select` should be present everywhere so this should be cross-platform and doesn't waste
11
11
  CPU resources. Keep in mind that each worker uses 2 file descriptors (reading and writing pipe).
12
+
13
+ Example
14
+ -------
15
+
16
+ ```ruby
17
+ require 'threadpool'
18
+
19
+ pool = ThreadPool.new
20
+ pool.resize(4)
21
+
22
+ 0.upto(10) { pool.process { sleep 2; puts 'lol' } }
23
+ ```
24
+
25
+ You should get 4 lols every 2 seconds.
data/lib/threadpool.rb CHANGED
@@ -36,19 +36,23 @@ class ThreadPool
36
36
  class Worker
37
37
  include Awakenable
38
38
 
39
- def initialize (watcher = nil)
40
- @watcher = watcher
41
- @mutex = Mutex.new
39
+ def initialize (pool)
40
+ @pool = pool
41
+ @mutex = Mutex.new
42
42
 
43
43
  @thread = Thread.new {
44
44
  loop do
45
45
  if @block
46
- @block.call(*@args) rescue nil
46
+ begin
47
+ @block.call(*@args)
48
+ rescue Exception => e
49
+ @pool.raise(e)
50
+ end
47
51
 
48
52
  @block = nil
49
53
  @args = nil
50
54
 
51
- @watcher.wake_up if @watcher
55
+ @pool.wake_up
52
56
  else
53
57
  sleep
54
58
 
@@ -97,24 +101,27 @@ class ThreadPool
97
101
 
98
102
  extend Forwardable
99
103
 
100
- def_delegators :@watcher, :kill, :die?, :dead?
104
+ attr_reader :watcher, :size
105
+ def_delegators :@watcher, :sleep, :wake_up, :kill, :die?, :dead?, :join
106
+ def_delegators :@current, :raise
101
107
 
102
108
  def initialize (size = 2)
103
109
  @size = 0
104
110
  @queue = Queue.new
105
111
  @pool = []
106
- @watcher = Worker.new
112
+ @watcher = Worker.new(self)
113
+ @current = Thread.current
107
114
 
108
115
  @watcher.process {
109
116
  loop do
110
- @watcher.sleep if @queue.empty?
111
- next if @queue.empty?
117
+ sleep if @queue.empty?
118
+ next if @queue.empty?
112
119
 
113
120
  begin
114
- worker = @pool.find(&:available?) or @watcher.sleep
121
+ worker = @pool.find(&:available?) or sleep
115
122
  end until worker
116
123
 
117
- break if @watcher.die?
124
+ break if die?
118
125
 
119
126
  args, block = @queue.pop
120
127
 
@@ -127,16 +134,12 @@ class ThreadPool
127
134
  resize(size)
128
135
  end
129
136
 
130
- def join
131
- @watcher.join
132
- end; alias wait join
133
-
134
137
  def resize (size)
135
138
  return if @size == size
136
139
 
137
140
  if @size < size
138
141
  1.upto(size - @size) {
139
- @pool << Worker.new(@watcher)
142
+ @pool << Worker.new(self)
140
143
  }
141
144
  else
142
145
  1.upto(@size - size) {
data/threadpool.gemspec CHANGED
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new {|s|
2
2
  s.name = 'threadpool'
3
- s.version = '0.0.1'
3
+ s.version = '0.0.1.1'
4
4
  s.author = 'meh.'
5
5
  s.email = 'meh@paranoici.org'
6
6
  s.homepage = 'http://github.com/meh/threadpool'
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: threadpool
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.1.1
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors: