fizx-thread_pool 0.1.0 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +3 -0
- data/lib/thread_pool.rb +32 -2
- data/test/test_thread_pool.rb +30 -0
- metadata +1 -1
data/CHANGELOG
CHANGED
data/lib/thread_pool.rb
CHANGED
@@ -9,6 +9,7 @@ class ThreadPool
|
|
9
9
|
if block = queue.shift
|
10
10
|
@active = true
|
11
11
|
block.call
|
12
|
+
block.complete = true
|
12
13
|
else
|
13
14
|
@active = false
|
14
15
|
sleep 0.01
|
@@ -22,17 +23,30 @@ class ThreadPool
|
|
22
23
|
end
|
23
24
|
end
|
24
25
|
|
26
|
+
attr_accessor :queue_limit
|
27
|
+
|
25
28
|
# Initialize with number of threads to run
|
26
|
-
def initialize(count)
|
29
|
+
def initialize(count, queue_limit = 0)
|
27
30
|
@executors = []
|
28
31
|
@queue = []
|
32
|
+
@queue_limit = queue_limit
|
29
33
|
@count = count
|
30
34
|
count.times { @executors << Executor.new(@queue) }
|
31
35
|
end
|
32
36
|
|
33
37
|
# Runs the block at some time in the near future
|
34
38
|
def execute(&block)
|
35
|
-
|
39
|
+
init_completable(block)
|
40
|
+
if @queue_limit > 0
|
41
|
+
sleep 0.01 until @queue.size < @queue_limit
|
42
|
+
end
|
43
|
+
@queue << block
|
44
|
+
end
|
45
|
+
|
46
|
+
# Runs the block at some time in the near future, and blocks until complete
|
47
|
+
def synchronous_execute(&block)
|
48
|
+
execute(&block)
|
49
|
+
sleep 0.01 until block.complete?
|
36
50
|
end
|
37
51
|
|
38
52
|
# Size of the task queue
|
@@ -54,4 +68,20 @@ class ThreadPool
|
|
54
68
|
def join
|
55
69
|
sleep 0.01 until @queue.empty? && @executors.all?{|e| !e.active}
|
56
70
|
end
|
71
|
+
|
72
|
+
protected
|
73
|
+
def init_completable(block)
|
74
|
+
block.extend(Completable)
|
75
|
+
block.complete = false
|
76
|
+
end
|
77
|
+
|
78
|
+
module Completable
|
79
|
+
def complete=(val)
|
80
|
+
@complete = val
|
81
|
+
end
|
82
|
+
|
83
|
+
def complete?
|
84
|
+
!!@complete
|
85
|
+
end
|
86
|
+
end
|
57
87
|
end
|
data/test/test_thread_pool.rb
CHANGED
@@ -30,6 +30,24 @@ class TestThreadPool < Test::Unit::TestCase
|
|
30
30
|
assert_equal n - THREADS, @pool.waiting
|
31
31
|
end
|
32
32
|
|
33
|
+
def test_queue_limit
|
34
|
+
n = 50
|
35
|
+
@foo = 0
|
36
|
+
@pool.queue_limit = 1
|
37
|
+
begin
|
38
|
+
Timeout::timeout(0.2) do
|
39
|
+
n.times {
|
40
|
+
@pool.execute { sleep 1 }
|
41
|
+
@foo += 1
|
42
|
+
}
|
43
|
+
end
|
44
|
+
rescue Timeout::Error
|
45
|
+
assert_equal @pool.queue_limit + @pool.size, @foo
|
46
|
+
else
|
47
|
+
assert false
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
33
51
|
def test_execution
|
34
52
|
Timeout::timeout(1) do
|
35
53
|
n = 50
|
@@ -41,4 +59,16 @@ class TestThreadPool < Test::Unit::TestCase
|
|
41
59
|
assert_equal n, @foo.length
|
42
60
|
end
|
43
61
|
end
|
62
|
+
|
63
|
+
def test_synchronous_execute
|
64
|
+
Timeout::timeout(1) do
|
65
|
+
@foo = false
|
66
|
+
@pool.execute { sleep 0.01; @foo = true }
|
67
|
+
assert !@foo
|
68
|
+
|
69
|
+
@foo = false
|
70
|
+
@pool.synchronous_execute { sleep 0.01; @foo = true }
|
71
|
+
assert @foo
|
72
|
+
end
|
73
|
+
end
|
44
74
|
end
|