work_queue 0.1.0 → 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- data/README.rdoc +18 -2
- data/lib/work_queue.rb +17 -11
- data/tasks/gem.rake +3 -3
- data/tasks/rdoc.rake +1 -0
- data/test/tc_work_queue.rb +9 -6
- metadata +3 -3
data/README.rdoc
CHANGED
@@ -1,4 +1,6 @@
|
|
1
|
-
|
1
|
+
= Description
|
2
|
+
|
3
|
+
A work queue is designed to coordinate work between a producer and a pool of worker threads.
|
2
4
|
When some task needs to be performed, the producer adds an object containing the task routine to the work queue.
|
3
5
|
If the work queue is full, the producer will block until a worker thread removes an object from the queue.
|
4
6
|
Eventually, one of the worker threads removes the object from the work queue and executes the routine.
|
@@ -8,4 +10,18 @@ Work queues are useful for several reasons:
|
|
8
10
|
* To easily perform tasks asynchronously and concurrently in your application;
|
9
11
|
* To let you focus on the work you actually want to perform without having to worry about the thread creation and management;
|
10
12
|
* To minimize overhead, by reusing previously constructed threads rather than creating new ones;
|
11
|
-
* To bound resource use, by setting a limit on the maximum number of simultaneously executing threads;
|
13
|
+
* To bound resource use, by setting a limit on the maximum number of simultaneously executing threads;
|
14
|
+
|
15
|
+
= Usage
|
16
|
+
|
17
|
+
Install the gem:
|
18
|
+
|
19
|
+
gem install work_queue
|
20
|
+
|
21
|
+
Run the code:
|
22
|
+
|
23
|
+
require 'rubygems'
|
24
|
+
require 'work_queue'
|
25
|
+
wq = WorkQueue.new
|
26
|
+
wq.enqueue_b { puts "Hello from the WorkQueue" }
|
27
|
+
wq.join
|
data/lib/work_queue.rb
CHANGED
@@ -6,7 +6,7 @@
|
|
6
6
|
# This file contains an implementation of a work queue structure.
|
7
7
|
#
|
8
8
|
# == Version
|
9
|
-
# 0.1.
|
9
|
+
# 0.1.1
|
10
10
|
#
|
11
11
|
# == Author
|
12
12
|
# Miguel Fonseca <fmmfonseca@gmail.com>
|
@@ -25,19 +25,19 @@ require 'timeout'
|
|
25
25
|
# = WorkQueue
|
26
26
|
#
|
27
27
|
# == Description
|
28
|
-
# A tunable work queue, designed to coordinate work between a producer and a
|
28
|
+
# A tunable work queue, designed to coordinate work between a producer and a pool of worker threads.
|
29
29
|
#
|
30
30
|
# == Usage
|
31
|
-
# wq = WorkQueue.new
|
31
|
+
# wq = WorkQueue.new
|
32
32
|
# wq.enqueue_b { puts "Hello from the WorkQueue" }
|
33
33
|
# wq.join
|
34
34
|
#
|
35
35
|
class WorkQueue
|
36
36
|
|
37
|
-
VERSION = "0.1.
|
37
|
+
VERSION = "0.1.1"
|
38
38
|
|
39
39
|
##
|
40
|
-
# Creates a new work queue.
|
40
|
+
# Creates a new work queue with the desired parameters.
|
41
41
|
#
|
42
42
|
# wq = WorkQueue.new(5,10,20)
|
43
43
|
#
|
@@ -57,6 +57,8 @@ class WorkQueue
|
|
57
57
|
# Returns the maximum number of worker threads.
|
58
58
|
# This value is set upon initialization and cannot be changed afterwards.
|
59
59
|
#
|
60
|
+
# wq = WorkQueue.new()
|
61
|
+
# wq.max_threads #=> Infinity
|
60
62
|
# wq = WorkQueue.new(1)
|
61
63
|
# wq.max_threads #=> 1
|
62
64
|
#
|
@@ -81,6 +83,8 @@ class WorkQueue
|
|
81
83
|
# Returns the maximum number of queued tasks.
|
82
84
|
# This value is set upon initialization and cannot be changed afterwards.
|
83
85
|
#
|
86
|
+
# wq = WorkQueue.new()
|
87
|
+
# wq.max_tasks #=> Infinity
|
84
88
|
# wq = WorkQueue.new(nil,1)
|
85
89
|
# wq.max_tasks #=> 1
|
86
90
|
#
|
@@ -116,7 +120,7 @@ class WorkQueue
|
|
116
120
|
end
|
117
121
|
|
118
122
|
##
|
119
|
-
# Schedules the given Proc for execution by a worker thread.
|
123
|
+
# Schedules the given Proc for future execution by a worker thread.
|
120
124
|
# If there is no space left in the queue, waits until space becomes available.
|
121
125
|
#
|
122
126
|
# wq = WorkQueue.new(1)
|
@@ -129,7 +133,7 @@ class WorkQueue
|
|
129
133
|
end
|
130
134
|
|
131
135
|
##
|
132
|
-
# Schedules the given Block for execution by a worker thread.
|
136
|
+
# Schedules the given Block for future execution by a worker thread.
|
133
137
|
# If there is no space left in the queue, waits until space becomes available.
|
134
138
|
#
|
135
139
|
# wq = WorkQueue.new(1)
|
@@ -142,7 +146,7 @@ class WorkQueue
|
|
142
146
|
end
|
143
147
|
|
144
148
|
##
|
145
|
-
# Waits until the tasks queue is empty.
|
149
|
+
# Waits until the tasks queue is empty and all worker threads have finished.
|
146
150
|
#
|
147
151
|
# wq = WorkQueue.new(1)
|
148
152
|
# wq.enqueue_b { sleep(1) }
|
@@ -194,10 +198,11 @@ class WorkQueue
|
|
194
198
|
end
|
195
199
|
|
196
200
|
##
|
197
|
-
#
|
201
|
+
# Enrolls a new worker thread.
|
202
|
+
# The request is only carried out if necessary.
|
198
203
|
#
|
199
204
|
def spawn_thread
|
200
|
-
if cur_threads < max_threads and @tasks.num_waiting <= 0
|
205
|
+
if cur_threads < max_threads and @tasks.num_waiting <= 0 and cur_tasks > 0
|
201
206
|
@threads_lock.synchronize {
|
202
207
|
@threads << Thread.new do
|
203
208
|
begin
|
@@ -211,7 +216,8 @@ class WorkQueue
|
|
211
216
|
end
|
212
217
|
|
213
218
|
##
|
214
|
-
#
|
219
|
+
# Instructs an idle worker thread to exit.
|
220
|
+
# The request is only carried out if necessary.
|
215
221
|
#
|
216
222
|
def dismiss_thread
|
217
223
|
@tasks << [Proc.new { Thread.exit }, nil] if cur_threads > 0
|
data/tasks/gem.rake
CHANGED
@@ -7,7 +7,7 @@ CLEAN.include("pkg")
|
|
7
7
|
spec = Gem::Specification.new do |s|
|
8
8
|
s.name = "work_queue"
|
9
9
|
s.version = WorkQueue::VERSION
|
10
|
-
s.summary = "A tunable work queue, designed to coordinate work between a producer and a
|
10
|
+
s.summary = "A tunable work queue, designed to coordinate work between a producer and a pool of worker threads."
|
11
11
|
s.homepage = "http://github.com/fmmfonseca/work_queue"
|
12
12
|
s.author = "Miguel Fonseca"
|
13
13
|
s.email = "fmmfonseca@gmail.com"
|
@@ -16,8 +16,8 @@ spec = Gem::Specification.new do |s|
|
|
16
16
|
s.files = FileList["LICENSE", "Rakefile", "README.rdoc", "tasks/*.rake", "lib/**/*.rb", "test/tc_*.rb"].to_a
|
17
17
|
s.test_files = Dir.glob("test/tc_*.rb")
|
18
18
|
s.has_rdoc = true
|
19
|
-
s.extra_rdoc_files = [
|
20
|
-
s.rdoc_options = [
|
19
|
+
s.extra_rdoc_files = %w[README.rdoc]
|
20
|
+
s.rdoc_options = %w[--line-numbers --inline-source --title WorkQueue --main README.rdoc]
|
21
21
|
end
|
22
22
|
|
23
23
|
# For a list of all attributes refer to http://rake.rubyforge.org/classes/Rake/PackageTask.html
|
data/tasks/rdoc.rake
CHANGED
@@ -4,6 +4,7 @@ CLEAN.include("doc")
|
|
4
4
|
|
5
5
|
# For a list of all attributes refer to http://rake.rubyforge.org/classes/Rake/RDocTask.html
|
6
6
|
Rake::RDocTask.new do |rd|
|
7
|
+
rd.title = "WorkQueue"
|
7
8
|
rd.main = "README.rdoc"
|
8
9
|
rd.rdoc_files.include("README.rdoc", "lib/**/*.rb")
|
9
10
|
rd.rdoc_dir = "doc"
|
data/test/tc_work_queue.rb
CHANGED
@@ -28,11 +28,11 @@ class TC_WorkQueue < Test::Unit::TestCase
|
|
28
28
|
def test_enqueue
|
29
29
|
s = String.new
|
30
30
|
wq = WorkQueue.new
|
31
|
-
#
|
31
|
+
# using proc
|
32
32
|
wq.enqueue_p(Proc.new { |str| str.replace("Hello #1") }, s)
|
33
33
|
wq.join
|
34
34
|
assert_equal(s, "Hello #1")
|
35
|
-
#
|
35
|
+
# using block
|
36
36
|
wq.enqueue_b(s) { |str| str.replace("Hello #2") }
|
37
37
|
wq.join
|
38
38
|
assert_equal(s, "Hello #2")
|
@@ -78,10 +78,13 @@ class TC_WorkQueue < Test::Unit::TestCase
|
|
78
78
|
def test_stress
|
79
79
|
a = []
|
80
80
|
m = Mutex.new
|
81
|
-
wq = WorkQueue.new(100)
|
82
|
-
(1..1000).each
|
83
|
-
wq.enqueue_b(a,m) { |str,mut|
|
84
|
-
|
81
|
+
wq = WorkQueue.new(100,200,0.1)
|
82
|
+
(1..1000).each do
|
83
|
+
wq.enqueue_b(a,m) { |str,mut|
|
84
|
+
sleep(0.01)
|
85
|
+
mut.synchronize { a.push nil }
|
86
|
+
}
|
87
|
+
end
|
85
88
|
wq.join
|
86
89
|
assert_equal(a.size, 1000)
|
87
90
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: work_queue
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Miguel Fonseca
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2009-11-
|
12
|
+
date: 2009-11-24 00:00:00 +00:00
|
13
13
|
default_executable:
|
14
14
|
dependencies: []
|
15
15
|
|
@@ -62,6 +62,6 @@ rubyforge_project:
|
|
62
62
|
rubygems_version: 1.3.5
|
63
63
|
signing_key:
|
64
64
|
specification_version: 3
|
65
|
-
summary: A tunable work queue, designed to coordinate work between a producer and a
|
65
|
+
summary: A tunable work queue, designed to coordinate work between a producer and a pool of worker threads.
|
66
66
|
test_files:
|
67
67
|
- test/tc_work_queue.rb
|