work_queue 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.
- 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
|