work_queue 0.1.2 → 1.0.0
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/Rakefile +1 -0
- data/lib/work_queue.rb +208 -208
- data/tasks/test.rake +15 -15
- data/test/tc_work_queue.rb +71 -71
- metadata +3 -7
- data/tasks/ftp.rake +0 -177
- data/tasks/gem.rake +0 -26
- data/tasks/rdoc.rake +0 -11
data/Rakefile
CHANGED
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.
|
9
|
+
# 1.0.0
|
10
10
|
#
|
11
11
|
# == Author
|
12
12
|
# Miguel Fonseca <fmmfonseca@gmail.com>
|
@@ -33,211 +33,211 @@ require 'timeout'
|
|
33
33
|
# wq.join
|
34
34
|
#
|
35
35
|
class WorkQueue
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
36
|
+
|
37
|
+
VERSION = "1.0.0"
|
38
|
+
|
39
|
+
##
|
40
|
+
# Creates a new work queue with the desired parameters.
|
41
|
+
#
|
42
|
+
# wq = WorkQueue.new(5,10,20)
|
43
|
+
#
|
44
|
+
def initialize(max_threads=nil, max_tasks=nil, keep_alive=60)
|
45
|
+
self.max_threads = max_threads
|
46
|
+
self.max_tasks = max_tasks
|
47
|
+
self.keep_alive = keep_alive
|
48
|
+
@threads = []
|
49
|
+
@threads_lock = Mutex.new
|
50
|
+
@tasks = max_tasks ? SizedQueue.new(max_tasks) : Queue.new
|
51
|
+
@threads.taint
|
52
|
+
@tasks.taint
|
53
|
+
self.taint
|
54
|
+
end
|
55
|
+
|
56
|
+
##
|
57
|
+
# Returns the maximum number of worker threads.
|
58
|
+
# This value is set upon initialization and cannot be changed afterwards.
|
59
|
+
#
|
60
|
+
# wq = WorkQueue.new()
|
61
|
+
# wq.max_threads #=> Infinity
|
62
|
+
# wq = WorkQueue.new(1)
|
63
|
+
# wq.max_threads #=> 1
|
64
|
+
#
|
65
|
+
def max_threads
|
66
|
+
@max_threads
|
67
|
+
end
|
68
|
+
|
69
|
+
##
|
70
|
+
# Returns the current number of worker threads.
|
71
|
+
# This value is just a snapshot, and may change immediately upon returning.
|
72
|
+
#
|
73
|
+
# wq = WorkQueue.new(10)
|
74
|
+
# wq.cur_threads #=> 0
|
75
|
+
# wq.enqueue_b {}
|
76
|
+
# wq.cur_threads #=> 1
|
77
|
+
#
|
78
|
+
def cur_threads
|
79
|
+
@threads.size
|
80
|
+
end
|
81
|
+
|
82
|
+
##
|
83
|
+
# Returns the maximum number of queued tasks.
|
84
|
+
# This value is set upon initialization and cannot be changed afterwards.
|
85
|
+
#
|
86
|
+
# wq = WorkQueue.new()
|
87
|
+
# wq.max_tasks #=> Infinity
|
88
|
+
# wq = WorkQueue.new(nil,1)
|
89
|
+
# wq.max_tasks #=> 1
|
90
|
+
#
|
91
|
+
def max_tasks
|
92
|
+
@max_tasks
|
93
|
+
end
|
94
|
+
|
95
|
+
##
|
96
|
+
# Returns the current number of queued tasks.
|
97
|
+
# This value is just a snapshot, and may change immediately upon returning.
|
98
|
+
#
|
99
|
+
# wq = WorkQueue.new(1)
|
100
|
+
# wq.enqueue_b { sleep(1) }
|
101
|
+
# wq.cur_tasks #=> 0
|
102
|
+
# wq.enqueue_b {}
|
103
|
+
# wq.cur_tasks #=> 1
|
104
|
+
#
|
105
|
+
def cur_tasks
|
106
|
+
@tasks.size
|
107
|
+
end
|
108
|
+
|
109
|
+
##
|
110
|
+
# Returns the number of seconds to keep worker threads alive waiting for new tasks.
|
111
|
+
# This value is set upon initialization and cannot be changed afterwards.
|
112
|
+
#
|
113
|
+
# wq = WorkQueue.new()
|
114
|
+
# wq.keep_alive #=> 60
|
115
|
+
# wq = WorkQueue.new(nil,nil,1)
|
116
|
+
# wq.keep_alive #=> 1
|
117
|
+
#
|
118
|
+
def keep_alive
|
119
|
+
@keep_alive
|
120
|
+
end
|
121
|
+
|
122
|
+
##
|
123
|
+
# Schedules the given Proc for future execution by a worker thread.
|
124
|
+
# If there is no space left in the queue, waits until space becomes available.
|
125
|
+
#
|
126
|
+
# wq = WorkQueue.new(1)
|
127
|
+
# wq.enqueue_p(Proc.new {})
|
128
|
+
#
|
129
|
+
def enqueue_p(proc, *args)
|
130
|
+
@tasks << [proc,args]
|
131
|
+
spawn_thread
|
132
|
+
self
|
133
|
+
end
|
134
|
+
|
135
|
+
##
|
136
|
+
# Schedules the given Block for future execution by a worker thread.
|
137
|
+
# If there is no space left in the queue, waits until space becomes available.
|
138
|
+
#
|
139
|
+
# wq = WorkQueue.new(1)
|
140
|
+
# wq.enqueue_b {}
|
141
|
+
#
|
142
|
+
def enqueue_b(*args, &block)
|
143
|
+
@tasks << [block,args]
|
144
|
+
spawn_thread
|
145
|
+
self
|
146
|
+
end
|
147
|
+
|
148
|
+
##
|
149
|
+
# Waits until the tasks queue is empty and all worker threads have finished.
|
150
|
+
#
|
151
|
+
# wq = WorkQueue.new(1)
|
152
|
+
# wq.enqueue_b { sleep(1) }
|
153
|
+
# wq.join
|
154
|
+
#
|
155
|
+
def join
|
156
|
+
cur_threads.times { dismiss_thread }
|
157
|
+
@threads.dup.each { |thread| thread.join }
|
158
|
+
self
|
159
|
+
end
|
160
|
+
|
161
|
+
##
|
162
|
+
# Stops all worker threads immediately, aborting any ongoing tasks.
|
163
|
+
#
|
164
|
+
# wq = WorkQueue.new(1)
|
165
|
+
# wq.enqueue_b { sleep(1) }
|
166
|
+
# wq.stop
|
167
|
+
#
|
168
|
+
def stop
|
169
|
+
@threads.dup.each { |thread| thread.exit.join }
|
170
|
+
@tasks.clear
|
171
|
+
self
|
172
|
+
end
|
173
|
+
|
174
|
+
private
|
175
|
+
|
176
|
+
##
|
177
|
+
# Sets the maximum number of worker threads.
|
178
|
+
#
|
179
|
+
def max_threads=(value)
|
180
|
+
raise ArgumentError, "the maximum number of threads must be positive" if value and value <= 0
|
181
|
+
@max_threads = value || 1.0/0
|
182
|
+
end
|
183
|
+
|
184
|
+
##
|
185
|
+
# Sets the maximum number of queued tasks.
|
186
|
+
#
|
187
|
+
def max_tasks=(value)
|
188
|
+
raise ArgumentError, "the maximum number of tasks must be positive" if value and value <= 0
|
189
|
+
@max_tasks = value || 1.0/0
|
190
|
+
end
|
191
|
+
|
192
|
+
##
|
193
|
+
# Sets the maximum time to keep worker threads alive waiting for new tasks.
|
194
|
+
#
|
195
|
+
def keep_alive=(value)
|
196
|
+
raise ArgumentError, "the keep-alive time must be positive" if value and value <= 0
|
197
|
+
@keep_alive = value || 1.0/0
|
198
|
+
end
|
199
|
+
|
200
|
+
##
|
201
|
+
# Enrolls a new worker thread.
|
202
|
+
# The request is only carried out if necessary.
|
203
|
+
#
|
204
|
+
def spawn_thread
|
205
|
+
if cur_threads < max_threads and @tasks.num_waiting <= 0 and cur_tasks > 0
|
206
|
+
@threads_lock.synchronize {
|
207
|
+
@threads << Thread.new do
|
208
|
+
begin
|
209
|
+
work()
|
210
|
+
ensure
|
211
|
+
@threads_lock.synchronize { @threads.delete(Thread.current) }
|
212
|
+
end
|
213
|
+
end
|
214
|
+
}
|
215
|
+
end
|
216
|
+
end
|
217
|
+
|
218
|
+
##
|
219
|
+
# Instructs an idle worker thread to exit.
|
220
|
+
# The request is only carried out if necessary.
|
221
|
+
#
|
222
|
+
def dismiss_thread
|
223
|
+
@tasks << [Proc.new { Thread.exit }, nil] if cur_threads > 0
|
224
|
+
end
|
225
|
+
|
226
|
+
##
|
227
|
+
# Repeatedly process the tasks queue.
|
228
|
+
#
|
229
|
+
def work
|
230
|
+
loop do
|
231
|
+
begin
|
232
|
+
proc, args = timeout(keep_alive) { @tasks.pop }
|
233
|
+
proc.call(*args)
|
234
|
+
rescue Timeout::Error
|
235
|
+
break
|
236
|
+
rescue Exception
|
237
|
+
# suppress exception
|
238
|
+
end
|
239
|
+
break if cur_threads > max_threads
|
240
|
+
end
|
241
|
+
end
|
242
|
+
|
243
243
|
end
|
data/tasks/test.rake
CHANGED
@@ -2,21 +2,21 @@ require 'rake/testtask'
|
|
2
2
|
|
3
3
|
namespace(:test) do
|
4
4
|
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
5
|
+
# For a list of all attributes refer to http://rake.rubyforge.org/classes/Rake/TestTask.html
|
6
|
+
Rake::TestTask.new(:unit) do |t|
|
7
|
+
t.libs << "test"
|
8
|
+
t.test_files = FileList['test/tc_*.rb']
|
9
|
+
t.verbose = true
|
10
|
+
t.warning = true
|
11
|
+
end
|
12
12
|
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
13
|
+
desc "Run tests on multiple ruby versions"
|
14
|
+
task(:compatibility) do
|
15
|
+
versions = %w[1.8.6 1.8.7 1.9.1 jruby]
|
16
|
+
system <<-CMD
|
17
|
+
bash -c 'source ~/.rvm/scripts/rvm;
|
18
|
+
rvm #{versions.join(',')} rake test:unit'
|
19
|
+
CMD
|
20
|
+
end
|
21
21
|
|
22
22
|
end
|
data/test/tc_work_queue.rb
CHANGED
@@ -18,75 +18,75 @@ require 'test/unit'
|
|
18
18
|
require 'lib/work_queue'
|
19
19
|
|
20
20
|
class TC_WorkQueue < Test::Unit::TestCase
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
21
|
+
|
22
|
+
# def setup
|
23
|
+
# end
|
24
|
+
|
25
|
+
# def teardown
|
26
|
+
# end
|
27
|
+
|
28
|
+
def test_enqueue
|
29
|
+
s = String.new
|
30
|
+
wq = WorkQueue.new
|
31
|
+
# using proc
|
32
|
+
wq.enqueue_p(Proc.new { |str| str.replace("Hello #1") }, s)
|
33
|
+
wq.join
|
34
|
+
assert_equal(s, "Hello #1")
|
35
|
+
# using block
|
36
|
+
wq.enqueue_b(s) { |str| str.replace("Hello #2") }
|
37
|
+
wq.join
|
38
|
+
assert_equal(s, "Hello #2")
|
39
|
+
end
|
40
|
+
|
41
|
+
def test_max_threads
|
42
|
+
assert_raise(ArgumentError) { WorkQueue.new(0) }
|
43
|
+
assert_raise(ArgumentError) { WorkQueue.new(-1) }
|
44
|
+
wq = WorkQueue.new(1)
|
45
|
+
assert_equal(wq.cur_threads, 0)
|
46
|
+
wq.enqueue_b { sleep(0.01) }
|
47
|
+
assert_equal(wq.cur_threads, 1)
|
48
|
+
wq.enqueue_b { sleep(0.01) }
|
49
|
+
assert_equal(wq.cur_threads, 1)
|
50
|
+
sleep(0.1)
|
51
|
+
assert_equal(wq.cur_threads, 1)
|
52
|
+
wq.join
|
53
|
+
end
|
54
|
+
|
55
|
+
def test_max_tasks
|
56
|
+
assert_raise(ArgumentError) { WorkQueue.new(nil,0) }
|
57
|
+
assert_raise(ArgumentError) { WorkQueue.new(nil,-1) }
|
58
|
+
wq = WorkQueue.new(1,1)
|
59
|
+
wq.enqueue_b { sleep(0.01) }
|
60
|
+
wq.enqueue_b { sleep(0.01) }
|
61
|
+
assert_equal(wq.cur_tasks, 1)
|
62
|
+
wq.enqueue_b { sleep(0.01) }
|
63
|
+
assert_equal(wq.cur_tasks, 1)
|
64
|
+
wq.join
|
65
|
+
end
|
66
|
+
|
67
|
+
def test_keep_alive
|
68
|
+
assert_raise(ArgumentError) { WorkQueue.new(nil,nil,0) }
|
69
|
+
assert_raise(ArgumentError) { WorkQueue.new(nil,nil,-1) }
|
70
|
+
wq = WorkQueue.new(1,1,0.01)
|
71
|
+
wq.enqueue_b { sleep(0.01) }
|
72
|
+
assert_equal(wq.cur_threads, 1)
|
73
|
+
sleep(0.1)
|
74
|
+
assert_equal(wq.cur_threads, 0)
|
75
|
+
wq.join
|
76
|
+
end
|
77
|
+
|
78
|
+
def test_stress
|
79
|
+
a = []
|
80
|
+
m = Mutex.new
|
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
|
88
|
+
wq.join
|
89
|
+
assert_equal(a.size, 1000)
|
90
|
+
end
|
91
|
+
|
92
92
|
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.
|
4
|
+
version: 1.0.0
|
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:
|
12
|
+
date: 2010-02-17 00:00:00 +00:00
|
13
13
|
default_executable:
|
14
14
|
dependencies: []
|
15
15
|
|
@@ -21,13 +21,11 @@ extensions: []
|
|
21
21
|
|
22
22
|
extra_rdoc_files:
|
23
23
|
- README.rdoc
|
24
|
+
- LICENSE
|
24
25
|
files:
|
25
26
|
- LICENSE
|
26
27
|
- Rakefile
|
27
28
|
- README.rdoc
|
28
|
-
- tasks/ftp.rake
|
29
|
-
- tasks/gem.rake
|
30
|
-
- tasks/rdoc.rake
|
31
29
|
- tasks/test.rake
|
32
30
|
- lib/work_queue.rb
|
33
31
|
- test/tc_work_queue.rb
|
@@ -39,8 +37,6 @@ post_install_message:
|
|
39
37
|
rdoc_options:
|
40
38
|
- --line-numbers
|
41
39
|
- --inline-source
|
42
|
-
- --title
|
43
|
-
- WorkQueue
|
44
40
|
- --main
|
45
41
|
- README.rdoc
|
46
42
|
require_paths:
|
data/tasks/ftp.rake
DELETED
@@ -1,177 +0,0 @@
|
|
1
|
-
require 'net/ftp'
|
2
|
-
require 'pathname'
|
3
|
-
require 'yaml'
|
4
|
-
require 'rubygems'
|
5
|
-
require 'rake'
|
6
|
-
require 'rake/tasklib'
|
7
|
-
|
8
|
-
module Rake
|
9
|
-
|
10
|
-
# = FTPTask
|
11
|
-
#
|
12
|
-
# == Description
|
13
|
-
# A Rake task that transfers local files to an FTP server.
|
14
|
-
#
|
15
|
-
# == Usage
|
16
|
-
# Rake::FTPTask.new do |t|
|
17
|
-
# t.host = "ftp.example.com"
|
18
|
-
# t.user_name = "user"
|
19
|
-
# t.password = "pass"
|
20
|
-
# t.path = "public_html/"
|
21
|
-
# t.upload_files = FileList["doc/**/*"].to_a
|
22
|
-
# end
|
23
|
-
#
|
24
|
-
# To avoid hard-coding the connection configuration into the source code, the task can obtain that data from a YAML file.
|
25
|
-
#
|
26
|
-
# Rake::FTPTask.new("ftp.yml") do |t|
|
27
|
-
# t.path = "public_html/"
|
28
|
-
# t.upload_files = FileList["doc/**/*"].to_a
|
29
|
-
# end
|
30
|
-
#
|
31
|
-
# # ftp.yml
|
32
|
-
# host = ftp.example.com
|
33
|
-
# user_name = user
|
34
|
-
# password = pass
|
35
|
-
# path = public_html/
|
36
|
-
#
|
37
|
-
class FTPTask < TaskLib
|
38
|
-
|
39
|
-
##
|
40
|
-
# The address of the server (default is nil).
|
41
|
-
#
|
42
|
-
attr_accessor :host
|
43
|
-
|
44
|
-
##
|
45
|
-
# The user name required to log into the server (default is "anonymous").
|
46
|
-
#
|
47
|
-
attr_accessor :user_name
|
48
|
-
|
49
|
-
##
|
50
|
-
# The password required for the selected user name (default is nil).
|
51
|
-
#
|
52
|
-
attr_accessor :password
|
53
|
-
|
54
|
-
##
|
55
|
-
# The (remote) base directory (default is "").
|
56
|
-
#
|
57
|
-
attr_accessor :path
|
58
|
-
|
59
|
-
##
|
60
|
-
# The array of files to be included in the FTP upload (default is []).
|
61
|
-
#
|
62
|
-
attr_accessor :upload_files
|
63
|
-
|
64
|
-
##
|
65
|
-
# The boolean to enable progress messages when true (default is false).
|
66
|
-
#
|
67
|
-
attr_accessor :verbose
|
68
|
-
|
69
|
-
##
|
70
|
-
# Creates a new FTP task.
|
71
|
-
#
|
72
|
-
def initialize(config_file=nil)
|
73
|
-
@host = nil
|
74
|
-
@user_name = "anonymous"
|
75
|
-
@password = nil
|
76
|
-
@path = ""
|
77
|
-
@upload_files = []
|
78
|
-
@verbose = false
|
79
|
-
@ftp = nil
|
80
|
-
@history = {}
|
81
|
-
load_config(config_file) unless config_file.nil?
|
82
|
-
yield self if block_given?
|
83
|
-
define
|
84
|
-
end
|
85
|
-
|
86
|
-
##
|
87
|
-
# Creates the tasks defined by this task lib.
|
88
|
-
#
|
89
|
-
def define
|
90
|
-
desc "Upload files to an FTP account"
|
91
|
-
task(:upload) do
|
92
|
-
connect
|
93
|
-
upload
|
94
|
-
disconnect
|
95
|
-
end
|
96
|
-
end
|
97
|
-
|
98
|
-
private
|
99
|
-
|
100
|
-
##
|
101
|
-
# Reads configuration values from a YAML file.
|
102
|
-
#
|
103
|
-
def load_config(file)
|
104
|
-
config = YAML::load_file(file)
|
105
|
-
@host = config["host"] || @host
|
106
|
-
@user_name = config["user_name"] || @user_name
|
107
|
-
@password = config["password"] || @password
|
108
|
-
@path = config["path"] || @path
|
109
|
-
end
|
110
|
-
|
111
|
-
##
|
112
|
-
# Establishes the FTP connection.
|
113
|
-
#
|
114
|
-
def connect
|
115
|
-
@ftp = Net::FTP.new(@host, @user_name, @password)
|
116
|
-
puts "Connected to #{@host}" if @verbose
|
117
|
-
puts "Using #{@ftp.binary ? "binary" : "text"} mode to transfer files" if @verbose
|
118
|
-
unless @path.nil? or @path.empty?
|
119
|
-
make_dirs(@path)
|
120
|
-
@ftp.chdir(@path)
|
121
|
-
puts "The working directory is now #{@ftp.getdir}" if @verbose
|
122
|
-
end
|
123
|
-
end
|
124
|
-
|
125
|
-
##
|
126
|
-
# Closes the FTP connection. Further remote operations are impossible.
|
127
|
-
#
|
128
|
-
def disconnect
|
129
|
-
@ftp.close
|
130
|
-
puts "Disconnected" if @verbose
|
131
|
-
end
|
132
|
-
|
133
|
-
##
|
134
|
-
# Iterates through the array of files.
|
135
|
-
#
|
136
|
-
def upload
|
137
|
-
puts "Uploading #{@upload_files.length} files..." if @verbose
|
138
|
-
@upload_files.each do |entry|
|
139
|
-
if File.directory?(entry)
|
140
|
-
make_dirs(entry)
|
141
|
-
else
|
142
|
-
put_file(entry)
|
143
|
-
end
|
144
|
-
end
|
145
|
-
end
|
146
|
-
|
147
|
-
##
|
148
|
-
# Transfers a local file to the server, relative to the current working directory.
|
149
|
-
#
|
150
|
-
def put_file(name)
|
151
|
-
puts "Uploading file #{name}" if @verbose
|
152
|
-
path = File.dirname(name)
|
153
|
-
make_dirs(path)
|
154
|
-
@ftp.put(name,name)
|
155
|
-
end
|
156
|
-
|
157
|
-
##
|
158
|
-
# Creates a directory and all its parent directories in the server, relative to the current working directory.
|
159
|
-
#
|
160
|
-
def make_dirs(name)
|
161
|
-
Pathname.new(name).descend do |dir|
|
162
|
-
if @history[dir].nil?
|
163
|
-
@history[dir] = true
|
164
|
-
puts "Creating directory #{dir}" if @verbose
|
165
|
-
@ftp.mkdir(dir) rescue nil
|
166
|
-
end
|
167
|
-
end
|
168
|
-
end
|
169
|
-
|
170
|
-
end
|
171
|
-
|
172
|
-
end
|
173
|
-
|
174
|
-
Rake::FTPTask.new("config/ftp.yml") do |ftp|
|
175
|
-
ftp.upload_files = FileList["doc/**/*"].to_a
|
176
|
-
ftp.verbose = true
|
177
|
-
end
|
data/tasks/gem.rake
DELETED
@@ -1,26 +0,0 @@
|
|
1
|
-
require 'rake/gempackagetask'
|
2
|
-
require 'lib/work_queue'
|
3
|
-
|
4
|
-
CLEAN.include("pkg")
|
5
|
-
|
6
|
-
# For a list of all attributes refer to http://docs.rubygems.org/read/chapter/20
|
7
|
-
spec = Gem::Specification.new do |s|
|
8
|
-
s.name = "work_queue"
|
9
|
-
s.version = WorkQueue::VERSION
|
10
|
-
s.summary = "A tunable work queue, designed to coordinate work between a producer and a pool of worker threads."
|
11
|
-
s.homepage = "http://github.com/fmmfonseca/work_queue"
|
12
|
-
s.author = "Miguel Fonseca"
|
13
|
-
s.email = "fmmfonseca@gmail.com"
|
14
|
-
|
15
|
-
s.required_ruby_version = ">= 1.8.6"
|
16
|
-
s.files = FileList["LICENSE", "Rakefile", "README.rdoc", "tasks/*.rake", "lib/**/*.rb", "test/tc_*.rb"].to_a
|
17
|
-
s.test_files = Dir.glob("test/tc_*.rb")
|
18
|
-
s.has_rdoc = true
|
19
|
-
s.extra_rdoc_files = %w[README.rdoc]
|
20
|
-
s.rdoc_options = %w[--line-numbers --inline-source --title WorkQueue --main README.rdoc]
|
21
|
-
end
|
22
|
-
|
23
|
-
# For a list of all attributes refer to http://rake.rubyforge.org/classes/Rake/PackageTask.html
|
24
|
-
Rake::GemPackageTask.new(spec) do |p|
|
25
|
-
p.need_zip = true
|
26
|
-
end
|
data/tasks/rdoc.rake
DELETED
@@ -1,11 +0,0 @@
|
|
1
|
-
require 'rake/rdoctask'
|
2
|
-
|
3
|
-
CLEAN.include("doc")
|
4
|
-
|
5
|
-
# For a list of all attributes refer to http://rake.rubyforge.org/classes/Rake/RDocTask.html
|
6
|
-
Rake::RDocTask.new do |rd|
|
7
|
-
rd.title = "WorkQueue"
|
8
|
-
rd.main = "README.rdoc"
|
9
|
-
rd.rdoc_files.include("README.rdoc", "lib/**/*.rb")
|
10
|
-
rd.rdoc_dir = "doc"
|
11
|
-
end
|