drbqs 0.0.17 → 0.0.18
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/docs/FormatExecute.md +44 -2
- data/example/group/execute.rb +19 -0
- data/example/group/server.rb +27 -0
- data/example/group/sum.rb +9 -0
- data/example/mandelbrot/README.md +8 -0
- data/example/mandelbrot/execute.rb +4 -0
- data/lib/drbqs/command_line/command_node.rb +1 -0
- data/lib/drbqs/execute/execute_node.rb +4 -21
- data/lib/drbqs/node/connection.rb +1 -2
- data/lib/drbqs/node/node.rb +163 -102
- data/lib/drbqs/node/state.rb +100 -35
- data/lib/drbqs/node/task_client.rb +46 -33
- data/lib/drbqs/server/message.rb +13 -7
- data/lib/drbqs/server/server.rb +57 -29
- data/lib/drbqs/server/server_hook.rb +19 -5
- data/lib/drbqs/server/test/node.rb +31 -6
- data/lib/drbqs/setting/node.rb +11 -2
- data/lib/drbqs/setting/server.rb +1 -1
- data/lib/drbqs/task/task.rb +26 -6
- data/lib/drbqs/task/task_generator.rb +2 -1
- data/lib/drbqs/utility/temporary.rb +27 -6
- data/lib/drbqs/utility/transfer/transfer_client.rb +10 -12
- data/lib/drbqs/version.rb +1 -1
- data/lib/drbqs/worker.rb +2 -0
- data/lib/drbqs/worker/forked_process.rb +100 -0
- data/lib/drbqs/worker/serialize.rb +66 -0
- data/lib/drbqs/worker/worker.rb +133 -0
- data/lib/drbqs/worker/worker_process_set.rb +219 -0
- data/spec/integration_test/01_basic_usage_spec.rb +3 -2
- data/spec/integration_test/06_node_exit_after_task_spec.rb +3 -2
- data/spec/integration_test/07_command_server_with_node_spec.rb +1 -0
- data/spec/integration_test/08_shutdown_unused_nodes_spec.rb +3 -2
- data/spec/integration_test/10_test_server_spec.rb +2 -2
- data/spec/integration_test/11_special_tasks_spec.rb +61 -0
- data/spec/integration_test/12_multiple_workers_spec.rb +43 -0
- data/spec/integration_test/definition/task_obj_definition.rb +33 -6
- data/spec/node/connection_spec.rb +6 -6
- data/spec/node/node_spec.rb +10 -2
- data/spec/node/state_spec.rb +146 -62
- data/spec/node/task_client_spec.rb +58 -53
- data/spec/server/message_spec.rb +10 -6
- data/spec/server/queue_spec.rb +7 -4
- data/spec/server/server_hook_spec.rb +28 -1
- data/spec/task/task_spec.rb +43 -6
- data/spec/utility/temporary_spec.rb +32 -9
- data/spec/worker/forked_process_spec.rb +66 -0
- data/spec/worker/serialize_spec.rb +73 -0
- data/spec/worker/worker_process_set_spec.rb +104 -0
- data/spec/worker/worker_spec.rb +127 -0
- metadata +34 -19
@@ -12,8 +12,9 @@ describe DRbQS::Server do
|
|
12
12
|
|
13
13
|
it "should send node exit" do
|
14
14
|
execute_node = DRbQS::Execution::ExecuteNode.new(@uri, nil, nil)
|
15
|
-
|
16
|
-
|
15
|
+
client_process_id = fork do
|
16
|
+
execute_node.execute(1)
|
17
|
+
end
|
17
18
|
th = Process.detach(client_process_id)
|
18
19
|
lambda do
|
19
20
|
@max_wait_time.times do |i|
|
@@ -7,12 +7,12 @@ describe DRbQS::Test::Server do
|
|
7
7
|
it "should execute as test." do
|
8
8
|
DRbQS.define_server do |server, argv, opts|
|
9
9
|
5.times do |i|
|
10
|
-
server.queue.add(DRbQS::Task.new(
|
10
|
+
server.queue.add(DRbQS::Task.new(TestCountCalc.new, :calc))
|
11
11
|
end
|
12
12
|
end
|
13
13
|
server = DRbQS.create_test_server({})
|
14
14
|
data = server.test_exec
|
15
15
|
data.should be_an_instance_of Hash
|
16
|
-
|
16
|
+
TestCountCalc.get.should == 5
|
17
17
|
end
|
18
18
|
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
|
2
|
+
|
3
|
+
require 'drbqs/task/task'
|
4
|
+
require_relative 'definition/task_obj_definition.rb'
|
5
|
+
|
6
|
+
describe DRbQS do
|
7
|
+
class TestValue
|
8
|
+
@file = File.join(File.dirname(__FILE__), 'value.txt')
|
9
|
+
|
10
|
+
def self.set(k, v)
|
11
|
+
open(@file, 'a+') do |f|
|
12
|
+
f.puts "#{k.to_s}\t#{v.to_s}"
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.get(val)
|
17
|
+
if File.exist?(@file)
|
18
|
+
File.read(@file).each_line do |l|
|
19
|
+
if /^#{val.to_s}/ =~ l
|
20
|
+
return l.split[1].to_i
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
nil
|
25
|
+
end
|
26
|
+
|
27
|
+
def self.clear
|
28
|
+
FileUtils.rm(@file) if File.exist?(@file)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
before(:all) do
|
33
|
+
@process_id, @uri = drbqs_fork_server(14110, :task => DRbQS::Task.new(Test1.new, :echo, args: [0])) do |server|
|
34
|
+
server.set_initialization_task(DRbQS::Task.new(TestValue, :set, args: [:first, 1]),
|
35
|
+
DRbQS::Task.new(TestValue, :set, args: [:second, 2]))
|
36
|
+
server.set_finalization_task(DRbQS::Task.new(TestValue, :set, args: [:third, 3]),
|
37
|
+
DRbQS::Task.new(TestValue, :set, args: [:fourth, 4]))
|
38
|
+
end
|
39
|
+
@node = DRbQS::Node.new(@uri, :log_file => $stdout, :continue => true)
|
40
|
+
end
|
41
|
+
|
42
|
+
it "should execute initialization tasks." do
|
43
|
+
@node.connect
|
44
|
+
TestValue.get(:first).should == 1
|
45
|
+
TestValue.get(:second).should == 2
|
46
|
+
end
|
47
|
+
|
48
|
+
it "should execute finalization tasks" do
|
49
|
+
@node.calculate
|
50
|
+
sleep(1) # Wait finish of task.
|
51
|
+
TestValue.get(:third).should == 3
|
52
|
+
TestValue.get(:fourth).should == 4
|
53
|
+
end
|
54
|
+
|
55
|
+
after(:all) do
|
56
|
+
TestValue.clear
|
57
|
+
lambda do
|
58
|
+
drbqs_wait_kill_server(@process_id, 30)
|
59
|
+
end.should_not raise_error
|
60
|
+
end
|
61
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
|
2
|
+
|
3
|
+
require 'drbqs/task/task'
|
4
|
+
require_relative 'definition/task_obj_definition.rb'
|
5
|
+
|
6
|
+
describe DRbQS do
|
7
|
+
before(:all) do
|
8
|
+
@dir = 'test_pid_dir'
|
9
|
+
FileUtils.mkdir(@dir) unless File.exist?(@dir)
|
10
|
+
@number_of_task = 10
|
11
|
+
@tasks = @number_of_task.times.map do |i|
|
12
|
+
DRbQS::Task.new(TestPID.new, :save, args: [@dir])
|
13
|
+
end
|
14
|
+
@process_number = 3
|
15
|
+
@process_id, @uri = drbqs_fork_server(14120, :task => @tasks)
|
16
|
+
@node = DRbQS::Node.new(@uri, :log_file => $stdout, :continue => true, :process => @process_number)
|
17
|
+
end
|
18
|
+
|
19
|
+
it "should calculate" do
|
20
|
+
@node.connect
|
21
|
+
lambda do
|
22
|
+
@node.calculate
|
23
|
+
end.should_not raise_error
|
24
|
+
paths = Dir.glob(File.join(@dir, '*')).select do |file|
|
25
|
+
/^\d+$/ =~ File.basename(file)
|
26
|
+
end
|
27
|
+
paths.uniq.should have(@process_number).items
|
28
|
+
n = 0
|
29
|
+
paths.each do |path|
|
30
|
+
n += File.read(path).to_i
|
31
|
+
end
|
32
|
+
n.should == @number_of_task
|
33
|
+
end
|
34
|
+
|
35
|
+
after(:all) do
|
36
|
+
TestCount.clear
|
37
|
+
lambda do
|
38
|
+
drbqs_wait_kill_server(@process_id)
|
39
|
+
end.should_not raise_error
|
40
|
+
FileUtils.rm_r(@dir) if File.exist?(@dir)
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|
@@ -1,14 +1,26 @@
|
|
1
|
-
class
|
2
|
-
@@
|
1
|
+
class TestCount
|
2
|
+
@@file = File.join(File.dirname(__FILE__), 'count.txt')
|
3
3
|
|
4
4
|
def echo(*args)
|
5
|
-
|
6
|
-
|
5
|
+
open(@@file, 'a+') do |f|
|
6
|
+
f.puts "count"
|
7
|
+
end
|
7
8
|
args
|
8
9
|
end
|
9
10
|
|
10
11
|
def self.get_execute_echo_number
|
11
|
-
@@
|
12
|
+
File.read(@@file).lines.to_a.size
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.clear
|
16
|
+
FileUtils.rm(@@file) if File.exist?(@@file)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
class Test1
|
21
|
+
def echo(*args)
|
22
|
+
puts "execute Test1#echo(*#{args.inspect.strip})"
|
23
|
+
args
|
12
24
|
end
|
13
25
|
end
|
14
26
|
|
@@ -48,7 +60,7 @@ class TestSum
|
|
48
60
|
end
|
49
61
|
end
|
50
62
|
|
51
|
-
class
|
63
|
+
class TestCountCalc
|
52
64
|
@@count = 0
|
53
65
|
|
54
66
|
def calc
|
@@ -61,3 +73,18 @@ class TestCount
|
|
61
73
|
n
|
62
74
|
end
|
63
75
|
end
|
76
|
+
|
77
|
+
class TestPID
|
78
|
+
def save(dir)
|
79
|
+
path = File.join(dir, "#{Process.pid}")
|
80
|
+
if File.exist?(path)
|
81
|
+
n = File.read(path).to_i + 1
|
82
|
+
else
|
83
|
+
n = 1
|
84
|
+
end
|
85
|
+
Kernel.open(path, 'w') do |f|
|
86
|
+
f.print n.to_s
|
87
|
+
end
|
88
|
+
true
|
89
|
+
end
|
90
|
+
end
|
@@ -20,9 +20,9 @@ describe DRbQS::Node::Connection do
|
|
20
20
|
end
|
21
21
|
|
22
22
|
it "should get initialization." do
|
23
|
-
ary = [
|
24
|
-
@message.write(ary)
|
25
|
-
@connection.get_initialization.should == ary
|
23
|
+
ary = DRbQS::Task.new([1, 2], :size).simple_drb_args
|
24
|
+
@message.write([:initialize, ary])
|
25
|
+
@connection.get_initialization.should == ary
|
26
26
|
end
|
27
27
|
|
28
28
|
it "should get no finalization method." do
|
@@ -30,9 +30,9 @@ describe DRbQS::Node::Connection do
|
|
30
30
|
end
|
31
31
|
|
32
32
|
it "should get finalization." do
|
33
|
-
ary = [
|
34
|
-
@message.write(ary)
|
35
|
-
@connection.get_finalization.should == ary
|
33
|
+
ary = DRbQS::Task.new([1, 2], :size).simple_drb_args
|
34
|
+
@message.write([:finalize, ary])
|
35
|
+
@connection.get_finalization.should == ary
|
36
36
|
end
|
37
37
|
|
38
38
|
it "should raise error for invalid signal." do
|
data/spec/node/node_spec.rb
CHANGED
@@ -22,12 +22,20 @@ describe DRbQS::Node do
|
|
22
22
|
end
|
23
23
|
|
24
24
|
it "should connect to server." do
|
25
|
+
node_number = 10
|
25
26
|
DRb::DRbObject.should_receive(:new_with_uri).and_return(@drb_object)
|
26
27
|
node_connection = mock('node connection')
|
27
|
-
node_connection.stub(:node_number).and_return(
|
28
|
+
node_connection.stub(:node_number).and_return(node_number)
|
28
29
|
node_connection.stub(:get_initialization).and_return(nil)
|
30
|
+
task_client = mock('task client')
|
31
|
+
task_client.stub(:node_number).and_return(node_number)
|
32
|
+
worker = mock('worker')
|
33
|
+
worker.stub(:create_process)
|
34
|
+
worker.stub(:on_error)
|
35
|
+
worker.stub(:on_result)
|
29
36
|
DRbQS::Node::Connection.should_receive(:new).and_return(node_connection)
|
30
|
-
DRbQS::Node::TaskClient.should_receive(:new)
|
37
|
+
DRbQS::Node::TaskClient.should_receive(:new).and_return(task_client)
|
38
|
+
DRbQS::Worker::ProcessSet.should_receive(:new).and_return(worker)
|
31
39
|
subject.connect
|
32
40
|
end
|
33
41
|
end
|
data/spec/node/state_spec.rb
CHANGED
@@ -1,79 +1,178 @@
|
|
1
1
|
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
|
2
2
|
|
3
3
|
describe DRbQS::Node::State do
|
4
|
+
def make_all_processes_wait
|
5
|
+
@process_number.times do |i|
|
6
|
+
subject.change(i, :wait)
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
before(:all) do
|
11
|
+
@process_number = 3
|
12
|
+
end
|
13
|
+
|
4
14
|
subject do
|
5
|
-
DRbQS::Node::State.new(:wait)
|
15
|
+
DRbQS::Node::State.new(:wait, @process_number)
|
6
16
|
end
|
7
17
|
|
8
|
-
context "when
|
18
|
+
context "when getting process number" do
|
19
|
+
it "should yield each process number." do
|
20
|
+
wids = []
|
21
|
+
subject.each_worker_id do |wid|
|
22
|
+
wids << wid
|
23
|
+
end
|
24
|
+
wids.sort.should == @process_number.times.to_a.sort
|
25
|
+
end
|
26
|
+
|
27
|
+
it "should get waiting process number." do
|
28
|
+
subject.waiting_worker_id.sort.should == @process_number.times.to_a.sort
|
29
|
+
end
|
30
|
+
|
31
|
+
it "should get waiting process number with not waiting process." do
|
32
|
+
waiting = []
|
33
|
+
@process_number.times do |i|
|
34
|
+
if i == 2
|
35
|
+
subject.change(i, :calculate)
|
36
|
+
else
|
37
|
+
waiting << i
|
38
|
+
end
|
39
|
+
end
|
40
|
+
subject.waiting_worker_id.sort.should == waiting
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
context "when requesting new tasks" do
|
9
45
|
before(:each) do
|
10
|
-
|
46
|
+
make_all_processes_wait
|
11
47
|
end
|
12
48
|
|
13
|
-
it "should
|
14
|
-
|
15
|
-
|
16
|
-
|
49
|
+
it "should request." do
|
50
|
+
subject.request?.should be_true
|
51
|
+
end
|
52
|
+
|
53
|
+
it "should request for all processes." do
|
54
|
+
subject.request_task_number.should == @process_number
|
55
|
+
end
|
56
|
+
|
57
|
+
it "should request except for one process." do
|
58
|
+
subject.change(0, :calculate)
|
59
|
+
subject.request_task_number.should == @process_number - 1
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
context "when state is :wait" do
|
64
|
+
before(:each) do
|
65
|
+
@process_number.times do |i|
|
66
|
+
subject.change(i, :wait)
|
67
|
+
end
|
17
68
|
end
|
18
69
|
|
19
70
|
it "should change to :sleep." do
|
20
|
-
|
21
|
-
|
22
|
-
|
71
|
+
subject.change_to_sleep
|
72
|
+
@process_number.times do |i|
|
73
|
+
subject.get_state(i).should == :sleep
|
74
|
+
end
|
23
75
|
end
|
24
76
|
|
25
|
-
it "should
|
26
|
-
|
27
|
-
|
28
|
-
|
77
|
+
it "should sleep." do
|
78
|
+
subject.sleep_with_auto_wakeup
|
79
|
+
@process_number.times do |i|
|
80
|
+
subject.get_state(i).should == :sleep
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
it "should wakeup." do
|
85
|
+
subject.wakeup_sleeping_worker
|
86
|
+
@process_number.times do |i|
|
87
|
+
subject.get_state(i).should == :wait
|
88
|
+
end
|
29
89
|
end
|
30
90
|
end
|
31
91
|
|
32
92
|
context "when state is :sleep" do
|
33
93
|
before(:each) do
|
34
|
-
|
94
|
+
@process_number.times do |i|
|
95
|
+
subject.change(i, :sleep)
|
96
|
+
end
|
35
97
|
end
|
36
98
|
|
37
99
|
it "should change to :sleep." do
|
38
|
-
|
39
|
-
|
40
|
-
|
100
|
+
subject.change_to_sleep
|
101
|
+
@process_number.times do |i|
|
102
|
+
subject.get_state(i).should == :sleep
|
103
|
+
end
|
41
104
|
end
|
42
105
|
|
43
|
-
it "should
|
44
|
-
|
45
|
-
|
46
|
-
|
106
|
+
it "should sleep." do
|
107
|
+
subject.sleep_with_auto_wakeup
|
108
|
+
@process_number.times do |i|
|
109
|
+
subject.get_state(i).should == :sleep
|
110
|
+
end
|
47
111
|
end
|
48
112
|
|
49
|
-
it "should
|
50
|
-
|
51
|
-
|
52
|
-
|
113
|
+
it "should wakeup." do
|
114
|
+
subject.wakeup_sleeping_worker
|
115
|
+
@process_number.times do |i|
|
116
|
+
subject.get_state(i).should == :wait
|
117
|
+
end
|
53
118
|
end
|
54
119
|
end
|
55
120
|
|
56
121
|
context "when state is :calculate" do
|
57
122
|
before(:each) do
|
58
|
-
|
123
|
+
@process_number.times do |i|
|
124
|
+
subject.change(i, :calculate)
|
125
|
+
end
|
59
126
|
end
|
60
127
|
|
61
128
|
it "should change to :sleep." do
|
62
|
-
|
63
|
-
|
64
|
-
|
129
|
+
subject.change_to_sleep
|
130
|
+
@process_number.times do |i|
|
131
|
+
subject.get_state(i).should == :calculate
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
it "should sleep." do
|
136
|
+
subject.sleep_with_auto_wakeup
|
137
|
+
@process_number.times do |i|
|
138
|
+
subject.get_state(i).should == :calculate
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
it "should wakeup." do
|
143
|
+
subject.wakeup_sleeping_worker
|
144
|
+
@process_number.times do |i|
|
145
|
+
subject.get_state(i).should == :calculate
|
146
|
+
end
|
147
|
+
end
|
148
|
+
end
|
149
|
+
|
150
|
+
context "when state is :calculate" do
|
151
|
+
before(:each) do
|
152
|
+
@process_number.times do |i|
|
153
|
+
subject.change(i, :exit)
|
154
|
+
end
|
65
155
|
end
|
66
156
|
|
67
157
|
it "should change to :sleep." do
|
68
|
-
|
69
|
-
|
70
|
-
|
158
|
+
subject.change_to_sleep
|
159
|
+
@process_number.times do |i|
|
160
|
+
subject.get_state(i).should == :exit
|
161
|
+
end
|
71
162
|
end
|
72
163
|
|
73
|
-
it "should
|
74
|
-
|
75
|
-
|
76
|
-
|
164
|
+
it "should sleep." do
|
165
|
+
subject.sleep_with_auto_wakeup
|
166
|
+
@process_number.times do |i|
|
167
|
+
subject.get_state(i).should == :exit
|
168
|
+
end
|
169
|
+
end
|
170
|
+
|
171
|
+
it "should wakeup." do
|
172
|
+
subject.wakeup_sleeping_worker
|
173
|
+
@process_number.times do |i|
|
174
|
+
subject.get_state(i).should == :exit
|
175
|
+
end
|
77
176
|
end
|
78
177
|
end
|
79
178
|
|
@@ -91,50 +190,35 @@ describe DRbQS::Node::State do
|
|
91
190
|
|
92
191
|
context "when setting load average" do
|
93
192
|
subject do
|
94
|
-
DRbQS::Node::State.new(:wait, :max_loadavg => 2)
|
193
|
+
DRbQS::Node::State.new(:wait, 1, :max_loadavg => 2)
|
95
194
|
end
|
96
195
|
|
97
196
|
it "should be true" do
|
98
197
|
subject.stub(:get_load_average).and_return([2.0, 2,0, 2.0])
|
99
|
-
subject.system_busy
|
198
|
+
subject.__send__(:system_busy?).should be_true
|
100
199
|
end
|
101
200
|
|
102
201
|
it "should be nil" do
|
103
202
|
subject.stub(:get_load_average).and_return([1.0, 1,0, 1.0])
|
104
|
-
subject.system_busy
|
203
|
+
subject.__send__(:system_busy?).should be_nil
|
105
204
|
end
|
106
205
|
end
|
107
206
|
|
108
|
-
context "when
|
109
|
-
before(:
|
110
|
-
|
111
|
-
end
|
112
|
-
|
113
|
-
it "should change to :wait." do
|
114
|
-
lambda do
|
115
|
-
subject.change_to_finish_calculating
|
116
|
-
end.should change { subject.state }.from(:calculate).to(:wait)
|
117
|
-
end
|
118
|
-
|
119
|
-
it "should change to :sleep." do
|
120
|
-
subject.change_to_sleep
|
121
|
-
lambda do
|
122
|
-
subject.change_to_finish_calculating
|
123
|
-
end.should change { subject.state }.from(:calculate).to(:sleep)
|
207
|
+
context "when setting auto wakeup" do
|
208
|
+
before(:all) do
|
209
|
+
@check_worker_id = 0
|
124
210
|
end
|
125
|
-
end
|
126
211
|
|
127
|
-
context "when setting auto wakeup" do
|
128
212
|
subject do
|
129
|
-
DRbQS::Node::State.new(:wait, :sleep_time => 0)
|
213
|
+
DRbQS::Node::State.new(:wait, 1, :sleep_time => 0)
|
130
214
|
end
|
131
215
|
|
132
216
|
it "should do nothing." do
|
217
|
+
make_all_processes_wait
|
133
218
|
subject.stub(:system_busy?).and_return(nil)
|
134
|
-
subject.change(:wait)
|
135
219
|
lambda do
|
136
220
|
subject.wakeup_automatically_for_unbusy_system
|
137
|
-
end.should_not change { subject.
|
221
|
+
end.should_not change { subject.get_state(@check_worker_id) }
|
138
222
|
end
|
139
223
|
|
140
224
|
it "should do nothing." do
|
@@ -142,7 +226,7 @@ describe DRbQS::Node::State do
|
|
142
226
|
subject.sleep_with_auto_wakeup
|
143
227
|
lambda do
|
144
228
|
subject.wakeup_automatically_for_unbusy_system
|
145
|
-
end.should change { subject.
|
229
|
+
end.should change { subject.get_state(@check_worker_id) }.from(:sleep).to(:wait)
|
146
230
|
end
|
147
231
|
end
|
148
232
|
end
|