drake 0.8.2.1.0.3 → 0.8.2.1.0.4
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/CHANGES.drake +5 -0
- data/README +5 -4
- data/Rakefile.drake +3 -34
- data/lib/rake.rb +6 -4
- data/lib/rake/parallel.rb +4 -7
- metadata +2 -12
- data/lib/rake/comp_tree/algorithm.rb +0 -234
- data/lib/rake/comp_tree/bucket_ipc.rb +0 -175
- data/lib/rake/comp_tree/driver.rb +0 -291
- data/lib/rake/comp_tree/error.rb +0 -51
- data/lib/rake/comp_tree/node.rb +0 -189
- data/lib/rake/comp_tree/quix/builtin/kernel/tap.rb +0 -57
- data/lib/rake/comp_tree/quix/diagnostic.rb +0 -92
- data/lib/rake/comp_tree/quix/kernel.rb +0 -109
- data/lib/rake/comp_tree/retriable_fork.rb +0 -66
- data/lib/rake/comp_tree/task_node.rb +0 -46
data/CHANGES.drake
CHANGED
data/README
CHANGED
@@ -33,10 +33,11 @@ dependency tree has not been properly defined. Consider
|
|
33
33
|
task :a => [:x, :y, :z]
|
34
34
|
|
35
35
|
With single-threaded Rake, _x_,_y_,_z_ will be invoked <em>in that
|
36
|
-
order</em> before _a_ is invoked
|
37
|
-
<code>drake --threads=N</code>
|
38
|
-
particular order of execution.
|
39
|
-
between _x_,_y_,_z_ above,
|
36
|
+
order</em> before _a_ is invoked (assuming there are no other rules
|
37
|
+
involving these tasks). However with <code>drake --threads=N</code>
|
38
|
+
(for N > 1), one should not expect any particular order of execution.
|
39
|
+
Since there is no dependency specified between _x_,_y_,_z_ above,
|
40
|
+
Drake is free to run them in any order.
|
40
41
|
|
41
42
|
If you wish _x_,_y_,_z_ to be invoked sequentially, then write
|
42
43
|
|
data/Rakefile.drake
CHANGED
@@ -5,38 +5,6 @@ require 'quix/subpackager'
|
|
5
5
|
require 'quix/fileutils'
|
6
6
|
require 'fileutils'
|
7
7
|
|
8
|
-
######################################################################
|
9
|
-
# repackage files from contrib/
|
10
|
-
|
11
|
-
task :generate_rb do
|
12
|
-
packages = {
|
13
|
-
:rake => {
|
14
|
-
:name_in_ruby => "Rake",
|
15
|
-
:lib_dir => "./lib",
|
16
|
-
:subpackages => {
|
17
|
-
:comp_tree => {
|
18
|
-
:name_in_ruby => "CompTree",
|
19
|
-
:sources => [
|
20
|
-
"driver",
|
21
|
-
"node",
|
22
|
-
"task_node",
|
23
|
-
"error",
|
24
|
-
"bucket_ipc",
|
25
|
-
"algorithm",
|
26
|
-
"retriable_fork",
|
27
|
-
"quix/diagnostic",
|
28
|
-
"quix/kernel",
|
29
|
-
"quix/builtin/kernel/tap",
|
30
|
-
],
|
31
|
-
:lib_dir => "./contrib/comp_tree/lib",
|
32
|
-
:ignore_root_rb => true,
|
33
|
-
},
|
34
|
-
},
|
35
|
-
},
|
36
|
-
}
|
37
|
-
Quix::Subpackager.run(packages)
|
38
|
-
end
|
39
|
-
|
40
8
|
######################################################################
|
41
9
|
# git
|
42
10
|
|
@@ -67,7 +35,7 @@ task :pull_mainline do
|
|
67
35
|
refs/heads/master:refs/heads/origin!)
|
68
36
|
end
|
69
37
|
|
70
|
-
task :pull_contrib => [ :init_contrib, :run_pull_contrib
|
38
|
+
task :pull_contrib => [ :init_contrib, :run_pull_contrib ]
|
71
39
|
|
72
40
|
######################################################################
|
73
41
|
# drake_release
|
@@ -88,7 +56,7 @@ end
|
|
88
56
|
|
89
57
|
def rubyforge(command, file)
|
90
58
|
sh("rubyforge",
|
91
|
-
|
59
|
+
command,
|
92
60
|
SPEC.rubyforge_project,
|
93
61
|
SPEC.rubyforge_project,
|
94
62
|
SPEC.version.to_s,
|
@@ -96,6 +64,7 @@ def rubyforge(command, file)
|
|
96
64
|
end
|
97
65
|
|
98
66
|
task :drake_finish_release do
|
67
|
+
sh("rubyforge", "login")
|
99
68
|
Dir.chdir("pkg") {
|
100
69
|
gem = "#{SPEC.name}-#{SPEC.version}.gem"
|
101
70
|
md5 = "#{gem}.md5"
|
data/lib/rake.rb
CHANGED
@@ -29,7 +29,7 @@
|
|
29
29
|
# as a library via a require statement, but it can be distributed
|
30
30
|
# independently as an application.
|
31
31
|
|
32
|
-
RAKEVERSION = '0.8.2.1.0.
|
32
|
+
RAKEVERSION = '0.8.2.1.0.4'
|
33
33
|
|
34
34
|
require 'rbconfig'
|
35
35
|
require 'getoptlong'
|
@@ -595,13 +595,14 @@ module Rake
|
|
595
595
|
end
|
596
596
|
return if @already_invoked
|
597
597
|
@already_invoked = true
|
598
|
-
|
598
|
+
prereqs = application.num_threads == 1 ? nil : Array.new
|
599
|
+
invoke_prerequisites(task_args, new_chain, prereqs)
|
599
600
|
if needed?
|
600
601
|
if application.num_threads == 1
|
601
602
|
execute(task_args)
|
602
603
|
else
|
603
604
|
# gather tasks for batch execution
|
604
|
-
application.parallel_tasks[name] = task_args
|
605
|
+
application.parallel_tasks[name] = [task_args, prereqs]
|
605
606
|
end
|
606
607
|
end
|
607
608
|
end
|
@@ -609,11 +610,12 @@ module Rake
|
|
609
610
|
protected :invoke_with_call_chain
|
610
611
|
|
611
612
|
# Invoke all the prerequisites of a task.
|
612
|
-
def invoke_prerequisites(task_args, invocation_chain)
|
613
|
+
def invoke_prerequisites(task_args, invocation_chain, accum=nil) #:nodoc:
|
613
614
|
@prerequisites.each { |n|
|
614
615
|
prereq = application[n, @scope]
|
615
616
|
prereq_args = task_args.new_scope(prereq.arg_names)
|
616
617
|
prereq.invoke_with_call_chain(prereq_args, invocation_chain)
|
618
|
+
accum << prereq if accum
|
617
619
|
}
|
618
620
|
end
|
619
621
|
|
data/lib/rake/parallel.rb
CHANGED
@@ -25,14 +25,11 @@ module Rake
|
|
25
25
|
#
|
26
26
|
# build the rest of the computation tree from task prereqs
|
27
27
|
#
|
28
|
-
parallel_tasks.each_pair { |task_name,
|
28
|
+
parallel_tasks.each_pair { |task_name, cache|
|
29
29
|
task = self[task_name]
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
else
|
34
|
-
raise "couldn't resolve #{task_name} prereq: #{child_name}"
|
35
|
-
end
|
30
|
+
task_args, prereqs = cache
|
31
|
+
children_names = prereqs.map { |child|
|
32
|
+
child.name.to_sym
|
36
33
|
}
|
37
34
|
driver.define(task_name.to_sym, *children_names) {
|
38
35
|
task.execute(task_args)
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: drake
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.8.2.1.0.
|
4
|
+
version: 0.8.2.1.0.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- James M. Lawrence
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2008-09-
|
12
|
+
date: 2008-09-13 00:00:00 -04:00
|
13
13
|
default_executable: drake
|
14
14
|
dependencies: []
|
15
15
|
|
@@ -52,16 +52,6 @@ files:
|
|
52
52
|
- bin/drake
|
53
53
|
- lib/rake/classic_namespace.rb
|
54
54
|
- lib/rake/clean.rb
|
55
|
-
- lib/rake/comp_tree/algorithm.rb
|
56
|
-
- lib/rake/comp_tree/bucket_ipc.rb
|
57
|
-
- lib/rake/comp_tree/driver.rb
|
58
|
-
- lib/rake/comp_tree/error.rb
|
59
|
-
- lib/rake/comp_tree/node.rb
|
60
|
-
- lib/rake/comp_tree/quix/builtin/kernel/tap.rb
|
61
|
-
- lib/rake/comp_tree/quix/diagnostic.rb
|
62
|
-
- lib/rake/comp_tree/quix/kernel.rb
|
63
|
-
- lib/rake/comp_tree/retriable_fork.rb
|
64
|
-
- lib/rake/comp_tree/task_node.rb
|
65
55
|
- lib/rake/contrib/compositepublisher.rb
|
66
56
|
- lib/rake/contrib/ftptools.rb
|
67
57
|
- lib/rake/contrib/publisher.rb
|
@@ -1,234 +0,0 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
######################################################
|
5
|
-
#
|
6
|
-
# **** DO NOT EDIT ****
|
7
|
-
#
|
8
|
-
# **** THIS IS A GENERATED FILE *****
|
9
|
-
#
|
10
|
-
######################################################
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
require 'rake/comp_tree/quix/diagnostic'
|
15
|
-
require 'rake/comp_tree/retriable_fork'
|
16
|
-
|
17
|
-
module Rake::CompTree
|
18
|
-
module Algorithm
|
19
|
-
include Quix::Diagnostic
|
20
|
-
|
21
|
-
def compute_multithreaded(root, num_threads, use_fork, buckets)
|
22
|
-
trace "Computing #{root.name} with #{num_threads} threads"
|
23
|
-
result = nil
|
24
|
-
mutex = Mutex.new
|
25
|
-
node_finished_condition = ConditionVariable.new
|
26
|
-
thread_wake_condition = ConditionVariable.new
|
27
|
-
threads = []
|
28
|
-
|
29
|
-
# workaround: jruby gives "run" status for waiting on
|
30
|
-
# condition variable
|
31
|
-
num_threads_ready = 0
|
32
|
-
|
33
|
-
num_threads.times { |thread_index|
|
34
|
-
threads << Thread.new {
|
35
|
-
#
|
36
|
-
# wait for main thread
|
37
|
-
#
|
38
|
-
mutex.synchronize {
|
39
|
-
trace "Thread #{thread_index} waiting to start"
|
40
|
-
num_threads_ready += 1
|
41
|
-
thread_wake_condition.wait(mutex)
|
42
|
-
}
|
43
|
-
|
44
|
-
while true
|
45
|
-
trace "Thread #{thread_index} node search"
|
46
|
-
|
47
|
-
#
|
48
|
-
# Done! Thread will exit.
|
49
|
-
#
|
50
|
-
break if mutex.synchronize {
|
51
|
-
result
|
52
|
-
}
|
53
|
-
|
54
|
-
#
|
55
|
-
# Lock the tree and find a node. The node we
|
56
|
-
# obtain, if any, is already locked.
|
57
|
-
#
|
58
|
-
node = mutex.synchronize {
|
59
|
-
find_node(root)
|
60
|
-
}
|
61
|
-
|
62
|
-
if node
|
63
|
-
trace "Thread #{thread_index} found node #{node.name}"
|
64
|
-
|
65
|
-
node_result =
|
66
|
-
compute_node(
|
67
|
-
node,
|
68
|
-
use_fork,
|
69
|
-
buckets ? buckets[thread_index] : nil)
|
70
|
-
|
71
|
-
mutex.synchronize {
|
72
|
-
node.result = node_result
|
73
|
-
}
|
74
|
-
|
75
|
-
#
|
76
|
-
# remove locks for this node (shared lock and own lock)
|
77
|
-
#
|
78
|
-
mutex.synchronize {
|
79
|
-
node.unlock
|
80
|
-
if node == root
|
81
|
-
#
|
82
|
-
# Root node was computed; we are done.
|
83
|
-
#
|
84
|
-
trace "Thread #{thread_index} got final answer"
|
85
|
-
result = root.result
|
86
|
-
end
|
87
|
-
node_finished_condition.signal
|
88
|
-
}
|
89
|
-
else
|
90
|
-
trace "Thread #{thread_index}: no node found; sleeping."
|
91
|
-
mutex.synchronize {
|
92
|
-
thread_wake_condition.wait(mutex)
|
93
|
-
}
|
94
|
-
end
|
95
|
-
end
|
96
|
-
trace "Thread #{thread_index} exiting"
|
97
|
-
}
|
98
|
-
}
|
99
|
-
|
100
|
-
trace "Main: waiting for threads to launch and block."
|
101
|
-
while true
|
102
|
-
break if mutex.synchronize {
|
103
|
-
num_threads_ready == num_threads
|
104
|
-
}
|
105
|
-
Thread.pass
|
106
|
-
end
|
107
|
-
|
108
|
-
trace "Main: entering main loop"
|
109
|
-
mutex.synchronize {
|
110
|
-
while true
|
111
|
-
trace "Main: waking threads"
|
112
|
-
thread_wake_condition.broadcast
|
113
|
-
|
114
|
-
if result
|
115
|
-
trace "Main: detected finish."
|
116
|
-
break
|
117
|
-
end
|
118
|
-
|
119
|
-
trace "Main: waiting for a node"
|
120
|
-
node_finished_condition.wait(mutex)
|
121
|
-
trace "Main: got a node"
|
122
|
-
end
|
123
|
-
}
|
124
|
-
|
125
|
-
trace "Main: waiting for threads to finish."
|
126
|
-
catch(:done) {
|
127
|
-
while true
|
128
|
-
mutex.synchronize {
|
129
|
-
throw :done if threads.all? { |thread|
|
130
|
-
thread.status == false
|
131
|
-
}
|
132
|
-
thread_wake_condition.broadcast
|
133
|
-
}
|
134
|
-
Thread.pass
|
135
|
-
end
|
136
|
-
}
|
137
|
-
|
138
|
-
trace "Main: computation done."
|
139
|
-
result
|
140
|
-
end
|
141
|
-
|
142
|
-
def find_node(node)
|
143
|
-
# --- only called inside mutex
|
144
|
-
trace "Looking for a node, starting with #{node.name}"
|
145
|
-
if node.result
|
146
|
-
#
|
147
|
-
# already computed
|
148
|
-
#
|
149
|
-
trace "#{node.name} has been computed"
|
150
|
-
nil
|
151
|
-
elsif node.children_results and node.try_lock
|
152
|
-
#
|
153
|
-
# Node is not computed and its children are computed;
|
154
|
-
# and we have the lock. Ready to compute.
|
155
|
-
#
|
156
|
-
node
|
157
|
-
else
|
158
|
-
#
|
159
|
-
# locked or children not computed; recurse to children
|
160
|
-
#
|
161
|
-
trace "Checking #{node.name}'s children"
|
162
|
-
node.each_child { |child|
|
163
|
-
if next_node = find_node(child)
|
164
|
-
return next_node
|
165
|
-
end
|
166
|
-
}
|
167
|
-
nil
|
168
|
-
end
|
169
|
-
end
|
170
|
-
|
171
|
-
def compute_node(node, use_fork, bucket)
|
172
|
-
if use_fork
|
173
|
-
trace "About to fork for node #{node.name}"
|
174
|
-
if bucket
|
175
|
-
#
|
176
|
-
# Use our assigned bucket to transfer the result.
|
177
|
-
#
|
178
|
-
fork_node(node) {
|
179
|
-
node.trace_compute
|
180
|
-
bucket.contents = node.compute
|
181
|
-
}
|
182
|
-
bucket.contents
|
183
|
-
else
|
184
|
-
#
|
185
|
-
# No bucket -- discarding result
|
186
|
-
#
|
187
|
-
fork_node(node) {
|
188
|
-
node.trace_compute
|
189
|
-
node.compute
|
190
|
-
}
|
191
|
-
true
|
192
|
-
end
|
193
|
-
else
|
194
|
-
#
|
195
|
-
# No fork
|
196
|
-
#
|
197
|
-
node.trace_compute
|
198
|
-
node.compute
|
199
|
-
end
|
200
|
-
end
|
201
|
-
|
202
|
-
def fork_node(node)
|
203
|
-
trace "About to fork for node #{node.name}"
|
204
|
-
process_id = RetriableFork.fork {
|
205
|
-
trace "Fork: process #{Process.pid}"
|
206
|
-
node.trace_compute
|
207
|
-
yield
|
208
|
-
trace "Fork: computation done"
|
209
|
-
}
|
210
|
-
trace "Waiting for process #{process_id}"
|
211
|
-
Process.wait(process_id)
|
212
|
-
trace "Process #{process_id} finished"
|
213
|
-
exitstatus = $?.exitstatus
|
214
|
-
if exitstatus != 0
|
215
|
-
trace "Process #{process_id} returned #{exitstatus}; exiting."
|
216
|
-
exit(1)
|
217
|
-
end
|
218
|
-
end
|
219
|
-
|
220
|
-
extend self
|
221
|
-
end
|
222
|
-
end
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
######################################################
|
227
|
-
#
|
228
|
-
# **** DO NOT EDIT ****
|
229
|
-
#
|
230
|
-
# **** THIS IS A GENERATED FILE *****
|
231
|
-
#
|
232
|
-
######################################################
|
233
|
-
|
234
|
-
|
@@ -1,175 +0,0 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
######################################################
|
5
|
-
#
|
6
|
-
# **** DO NOT EDIT ****
|
7
|
-
#
|
8
|
-
# **** THIS IS A GENERATED FILE *****
|
9
|
-
#
|
10
|
-
######################################################
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
require 'drb'
|
15
|
-
require 'thread'
|
16
|
-
|
17
|
-
require 'rake/comp_tree/retriable_fork'
|
18
|
-
require 'rake/comp_tree/quix/diagnostic'
|
19
|
-
require 'rake/comp_tree/quix/builtin/kernel/tap'
|
20
|
-
|
21
|
-
module Rake::CompTree
|
22
|
-
module BucketIPC
|
23
|
-
class Bucket
|
24
|
-
include Quix::Diagnostic
|
25
|
-
include RetriableFork
|
26
|
-
|
27
|
-
def initialize(address, timeout, wait_interval)
|
28
|
-
trace "Making bucket with address #{address}"
|
29
|
-
|
30
|
-
@remote_pid = fork {
|
31
|
-
own_object = Class.new {
|
32
|
-
attr_accessor(:contents)
|
33
|
-
}.new
|
34
|
-
server = DRb.start_service(address, own_object)
|
35
|
-
debug {
|
36
|
-
server.verbose = true
|
37
|
-
}
|
38
|
-
DRb.thread.join
|
39
|
-
}
|
40
|
-
|
41
|
-
@remote_object = DRbObject.new_with_uri(address)
|
42
|
-
@address = address
|
43
|
-
@timeout = timeout
|
44
|
-
@wait_interval = wait_interval
|
45
|
-
end
|
46
|
-
|
47
|
-
attr_accessor(:timeout, :wait_interval)
|
48
|
-
attr_reader(:address)
|
49
|
-
|
50
|
-
def contents=(new_contents)
|
51
|
-
connect {
|
52
|
-
@remote_object.contents = new_contents
|
53
|
-
}
|
54
|
-
end
|
55
|
-
|
56
|
-
def contents
|
57
|
-
connect {
|
58
|
-
@remote_object.contents
|
59
|
-
}
|
60
|
-
end
|
61
|
-
|
62
|
-
def stop
|
63
|
-
Process.kill("TERM", @remote_pid)
|
64
|
-
end
|
65
|
-
|
66
|
-
private
|
67
|
-
|
68
|
-
def connect
|
69
|
-
begin
|
70
|
-
return yield
|
71
|
-
rescue DRb::DRbConnError
|
72
|
-
start = Time.now
|
73
|
-
begin
|
74
|
-
Kernel.sleep(@wait_interval)
|
75
|
-
return yield
|
76
|
-
rescue DRb::DRbConnError
|
77
|
-
if Time.now - start > @timeout
|
78
|
-
raise
|
79
|
-
end
|
80
|
-
retry
|
81
|
-
end
|
82
|
-
end
|
83
|
-
end
|
84
|
-
end
|
85
|
-
|
86
|
-
class DriverBase
|
87
|
-
def initialize(addresses, timeout, wait_interval)
|
88
|
-
begin
|
89
|
-
@buckets = addresses.map { |address|
|
90
|
-
Bucket.new(address, timeout, wait_interval)
|
91
|
-
}
|
92
|
-
if block_given?
|
93
|
-
yield @buckets
|
94
|
-
end
|
95
|
-
ensure
|
96
|
-
if block_given?
|
97
|
-
stop
|
98
|
-
end
|
99
|
-
end
|
100
|
-
end
|
101
|
-
|
102
|
-
def stop
|
103
|
-
if defined?(@buckets)
|
104
|
-
@buckets.each { |bucket|
|
105
|
-
bucket.stop
|
106
|
-
}
|
107
|
-
end
|
108
|
-
end
|
109
|
-
end
|
110
|
-
|
111
|
-
class Driver < DriverBase
|
112
|
-
DEFAULTS = {
|
113
|
-
:timeout => 0.5,
|
114
|
-
:wait_interval => 0.05,
|
115
|
-
:port_start => 18181,
|
116
|
-
}
|
117
|
-
|
118
|
-
module BucketCounter
|
119
|
-
@mutex = Mutex.new
|
120
|
-
@count = 0
|
121
|
-
class << self
|
122
|
-
def increment_count
|
123
|
-
@mutex.synchronize {
|
124
|
-
@count += 1
|
125
|
-
}
|
126
|
-
end
|
127
|
-
|
128
|
-
def map_indexes(num_buckets)
|
129
|
-
Array.new.tap { |result|
|
130
|
-
num_buckets.times {
|
131
|
-
result << yield(increment_count)
|
132
|
-
}
|
133
|
-
}
|
134
|
-
end
|
135
|
-
end
|
136
|
-
end
|
137
|
-
|
138
|
-
def initialize(num_buckets, opts_in = {})
|
139
|
-
opts = DEFAULTS.merge(opts_in)
|
140
|
-
|
141
|
-
addresses =
|
142
|
-
if RetriableFork::HAVE_FORK
|
143
|
-
#
|
144
|
-
# Assume the existence of fork implies a unix machine.
|
145
|
-
#
|
146
|
-
require 'drb/unix'
|
147
|
-
basename = "drbunix://#{Dir.tmpdir}/bucket.#{Process.pid}.#{rand}"
|
148
|
-
BucketCounter.map_indexes(num_buckets) { |index|
|
149
|
-
"#{basename}.#{index}"
|
150
|
-
}
|
151
|
-
else
|
152
|
-
#
|
153
|
-
# Fallback: use the default socket.
|
154
|
-
#
|
155
|
-
BucketCounter.map_indexes(num_buckets) { |index|
|
156
|
-
"druby://localhost:#{opts[:port_start] + index}"
|
157
|
-
}
|
158
|
-
end
|
159
|
-
super(addresses, opts[:timeout], opts[:wait_interval])
|
160
|
-
end
|
161
|
-
end
|
162
|
-
end
|
163
|
-
end
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
######################################################
|
168
|
-
#
|
169
|
-
# **** DO NOT EDIT ****
|
170
|
-
#
|
171
|
-
# **** THIS IS A GENERATED FILE *****
|
172
|
-
#
|
173
|
-
######################################################
|
174
|
-
|
175
|
-
|