drbqs 0.0.14 → 0.0.15
Sign up to get free protection for your applications and to get access to all the features.
- data/VERSION +1 -1
- data/bin/drbqs-execute +6 -0
- data/bin/drbqs-manage +2 -2
- data/bin/drbqs-node +2 -2
- data/bin/drbqs-server +2 -2
- data/bin/drbqs-ssh +2 -2
- data/drbqs.gemspec +53 -16
- data/example/error_server/error.rb +6 -0
- data/example/error_server/server_def.rb +7 -0
- data/example/{error → error_task}/error.rb +0 -0
- data/example/{error → error_task}/server_def.rb +0 -0
- data/example/sum2/execute_def.rb +27 -0
- data/lib/drbqs/command_line/argument.rb +29 -0
- data/lib/drbqs/command_line/command_base.rb +81 -0
- data/lib/drbqs/command_line/command_execute.rb +33 -0
- data/lib/drbqs/command_line/command_line.rb +19 -0
- data/lib/drbqs/command_line/command_manage.rb +34 -0
- data/lib/drbqs/command_line/command_node.rb +26 -0
- data/lib/drbqs/command_line/command_server.rb +41 -0
- data/lib/drbqs/command_line/command_ssh.rb +51 -0
- data/lib/drbqs/command_line/option_setting.rb +42 -0
- data/lib/drbqs/execute/process_define.rb +213 -0
- data/lib/drbqs/execute/register.rb +147 -0
- data/lib/drbqs/{utility → execute}/server_define.rb +7 -14
- data/lib/drbqs/manage/execute_node.rb +4 -2
- data/lib/drbqs/manage/manage.rb +23 -16
- data/lib/drbqs/manage/send_signal.rb +31 -4
- data/lib/drbqs/manage/ssh_execute.rb +50 -6
- data/lib/drbqs/manage/ssh_shell.rb +95 -50
- data/lib/drbqs/node/connection.rb +1 -1
- data/lib/drbqs/node/node.rb +67 -17
- data/lib/drbqs/node/state.rb +109 -0
- data/lib/drbqs/node/task_client.rb +7 -7
- data/lib/drbqs/server/history.rb +16 -0
- data/lib/drbqs/server/message.rb +80 -15
- data/lib/drbqs/server/node_list.rb +16 -3
- data/lib/drbqs/server/prof.rb +48 -0
- data/lib/drbqs/server/queue.rb +20 -2
- data/lib/drbqs/server/server.rb +112 -70
- data/lib/drbqs/server/server_hook.rb +26 -6
- data/lib/drbqs/server/test/node.rb +34 -0
- data/lib/drbqs/server/test/server.rb +74 -0
- data/lib/drbqs/setting/base.rb +120 -0
- data/lib/drbqs/setting/data_container.rb +39 -0
- data/lib/drbqs/setting/execute.rb +71 -0
- data/lib/drbqs/setting/manage.rb +163 -0
- data/lib/drbqs/setting/node.rb +84 -0
- data/lib/drbqs/setting/server.rb +230 -0
- data/lib/drbqs/setting/setting.rb +14 -0
- data/lib/drbqs/setting/source.rb +220 -0
- data/lib/drbqs/setting/ssh.rb +165 -0
- data/lib/drbqs/task/task_generator.rb +4 -2
- data/lib/drbqs/utility/misc.rb +15 -1
- data/lib/drbqs/utility/temporary.rb +4 -2
- data/lib/drbqs.rb +3 -2
- data/spec/command_line/command_base_spec.rb +47 -0
- data/spec/{utility/command_line → command_line}/commands_spec.rb +3 -3
- data/spec/command_line/option_setting_spec.rb +29 -0
- data/spec/execute/def/execute1.rb +24 -0
- data/spec/execute/def/no_def.rb +2 -0
- data/spec/execute/process_define_spec.rb +167 -0
- data/spec/execute/register_spec.rb +77 -0
- data/spec/{utility → execute}/server_define_spec.rb +0 -0
- data/spec/integration_test/01_basic_usage_spec.rb +1 -1
- data/spec/integration_test/02_use_generator_spec.rb +1 -1
- data/spec/integration_test/03_use_temporary_file_spec.rb +1 -1
- data/spec/integration_test/04_use_unix_domain_spec.rb +1 -1
- data/spec/integration_test/05_server_exit_signal_spec.rb +1 -1
- data/spec/integration_test/06_node_exit_after_task_spec.rb +1 -1
- data/spec/integration_test/07_command_server_with_node_spec.rb +19 -16
- data/spec/integration_test/08_shutdown_unused_nodes_spec.rb +38 -0
- data/spec/integration_test/09_server_process_data_spec.rb +74 -0
- data/spec/integration_test/10_test_server_spec.rb +18 -0
- data/spec/integration_test/definition/task_obj_definition.rb +14 -0
- data/spec/manage/send_signal_spec.rb +8 -0
- data/spec/manage/ssh_shell_spec.rb +1 -1
- data/spec/node/state_spec.rb +148 -0
- data/spec/node/task_client_spec.rb +15 -0
- data/spec/server/history_spec.rb +51 -20
- data/spec/server/message_spec.rb +7 -2
- data/spec/server/node_list_spec.rb +1 -1
- data/spec/server/queue_spec.rb +93 -4
- data/spec/server/server_hook_spec.rb +62 -0
- data/spec/setting/base_spec.rb +35 -0
- data/spec/setting/data_container_spec.rb +92 -0
- data/spec/setting/execute_spec.rb +51 -0
- data/spec/setting/manage_spec.rb +63 -0
- data/spec/setting/node_spec.rb +43 -0
- data/spec/setting/server_spec.rb +46 -0
- data/spec/setting/source_spec.rb +245 -0
- data/spec/spec_helper.rb +17 -10
- data/spec/utility/argument_spec.rb +7 -7
- metadata +179 -146
- data/lib/drbqs/utility/argument.rb +0 -27
- data/lib/drbqs/utility/command_line/command_base.rb +0 -27
- data/lib/drbqs/utility/command_line/command_manage.rb +0 -121
- data/lib/drbqs/utility/command_line/command_node.rb +0 -103
- data/lib/drbqs/utility/command_line/command_server.rb +0 -165
- data/lib/drbqs/utility/command_line/command_ssh.rb +0 -126
- data/lib/drbqs/utility/command_line.rb +0 -15
- data/spec/utility/command_line/command_base_spec.rb +0 -33
@@ -9,6 +9,7 @@ module DRbQS
|
|
9
9
|
@id = 0
|
10
10
|
@list = {}
|
11
11
|
@check = []
|
12
|
+
@prepare_to_exit = []
|
12
13
|
@history = DRbQS::Server::History.new
|
13
14
|
end
|
14
15
|
|
@@ -27,14 +28,15 @@ module DRbQS
|
|
27
28
|
@check = @list.keys
|
28
29
|
end
|
29
30
|
|
30
|
-
def delete(id)
|
31
|
+
def delete(id, history_state)
|
31
32
|
@list.delete(id)
|
32
|
-
@
|
33
|
+
@prepare_to_exit.delete(id)
|
34
|
+
@history.set(id, history_state)
|
33
35
|
end
|
34
36
|
|
35
37
|
def delete_not_alive
|
36
38
|
@check.each do |id|
|
37
|
-
delete(id)
|
39
|
+
delete(id, :disconnect)
|
38
40
|
end
|
39
41
|
deleted = @check
|
40
42
|
@check = []
|
@@ -52,6 +54,17 @@ module DRbQS
|
|
52
54
|
def exist?(id)
|
53
55
|
@list.find { |a| a[0] == id }
|
54
56
|
end
|
57
|
+
|
58
|
+
def prepare_to_exit?(node_id)
|
59
|
+
@prepare_to_exit.include?(node_id)
|
60
|
+
end
|
61
|
+
|
62
|
+
def add_to_preparation_to_exit(node_id)
|
63
|
+
unless prepare_to_exit?(node_id)
|
64
|
+
@history.set(node_id, :set_exitting)
|
65
|
+
@prepare_to_exit << node_id
|
66
|
+
end
|
67
|
+
end
|
55
68
|
end
|
56
69
|
|
57
70
|
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
require 'ruby-prof'
|
2
|
+
|
3
|
+
module DRbQS
|
4
|
+
class Prof
|
5
|
+
PRINTER_TYPE = [:flat, :graph, :graphhtml, :calltree]
|
6
|
+
|
7
|
+
# :flat
|
8
|
+
# :graph
|
9
|
+
# :graphhtml
|
10
|
+
# :calltree
|
11
|
+
def initialize(printer_type, output)
|
12
|
+
@printer_type = printer_type
|
13
|
+
unless PRINTER_TYPE.include?(@printer_type)
|
14
|
+
raise "Invalid printer type: #{@printer_type.inspect}"
|
15
|
+
end
|
16
|
+
@output = output
|
17
|
+
end
|
18
|
+
|
19
|
+
def get_printer(result)
|
20
|
+
case @printer_type
|
21
|
+
when :flat
|
22
|
+
RubyProf::FlatPrinter.new(result)
|
23
|
+
when :graph
|
24
|
+
RubyProf::GraphPrinter.new(result)
|
25
|
+
when :graphhtml
|
26
|
+
RubyProf::GraphHtmlPrinter.new(result)
|
27
|
+
when :calltree
|
28
|
+
RubyProf::CallTreePrinter.new(result)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
private :get_printer
|
32
|
+
|
33
|
+
def start
|
34
|
+
RubyProf.start
|
35
|
+
end
|
36
|
+
|
37
|
+
def finish
|
38
|
+
printer = get_printer(RubyProf.stop)
|
39
|
+
if IO === @output
|
40
|
+
printer.print(@output)
|
41
|
+
else
|
42
|
+
Kernel.open(@output, 'w') do |f|
|
43
|
+
printer.print(f)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
data/lib/drbqs/server/queue.rb
CHANGED
@@ -12,7 +12,7 @@ module DRbQS
|
|
12
12
|
@task_id = 0
|
13
13
|
@cache = {}
|
14
14
|
@calculating = Hash.new { |hash, key| hash[key] = Array.new }
|
15
|
-
@history = DRbQS::Server::
|
15
|
+
@history = DRbQS::Server::TaskHistory.new
|
16
16
|
@logger = logger
|
17
17
|
end
|
18
18
|
|
@@ -105,12 +105,20 @@ module DRbQS
|
|
105
105
|
@calculating.inject(0) { |s, key_val| s + key_val[1].size }
|
106
106
|
end
|
107
107
|
|
108
|
+
def stocked_task_number
|
109
|
+
@cache.size - calculating_task_number
|
110
|
+
end
|
111
|
+
|
112
|
+
def finished_task_number
|
113
|
+
@history.finished_task_number
|
114
|
+
end
|
115
|
+
|
108
116
|
# If queue is empty, that is, there is no tasks to calculate next,
|
109
117
|
# this method returns true. Otherwise, false.
|
110
118
|
# Even if there are calculating tasks,
|
111
119
|
# the method can return true.
|
112
120
|
def empty?
|
113
|
-
|
121
|
+
stocked_task_number == 0
|
114
122
|
end
|
115
123
|
|
116
124
|
# If there are no tasks in queue and calculating,
|
@@ -122,6 +130,16 @@ module DRbQS
|
|
122
130
|
def all_logs
|
123
131
|
@history.log_strings
|
124
132
|
end
|
133
|
+
|
134
|
+
def calculating_nodes
|
135
|
+
nodes = []
|
136
|
+
@calculating.each do |node_id, tasks|
|
137
|
+
if tasks.size > 0
|
138
|
+
nodes << node_id
|
139
|
+
end
|
140
|
+
end
|
141
|
+
nodes.sort!
|
142
|
+
end
|
125
143
|
end
|
126
144
|
|
127
145
|
end
|
data/lib/drbqs/server/server.rb
CHANGED
@@ -32,6 +32,8 @@ module DRbQS
|
|
32
32
|
# Set the time interval of checking alive nodes.
|
33
33
|
# :finish_exit
|
34
34
|
# Exit programs in finish_hook.
|
35
|
+
# :shutdown_unused_nodes
|
36
|
+
# Shutdown unused nodes.
|
35
37
|
# :signal_trap
|
36
38
|
# Set trapping signal.
|
37
39
|
# :sftp_user
|
@@ -56,9 +58,10 @@ module DRbQS
|
|
56
58
|
@queue= DRbQS::Server::Queue.new(@ts[:queue], @ts[:result], @logger)
|
57
59
|
@check_alive = DRbQS::Server::CheckAlive.new(opts[:check_alive])
|
58
60
|
@task_generator = []
|
59
|
-
hook_init(opts[:finish_exit])
|
61
|
+
hook_init(opts[:finish_exit], opts[:shutdown_unused_nodes])
|
60
62
|
set_signal_trap if opts[:signal_trap]
|
61
63
|
@finalization_task = nil
|
64
|
+
@data_storage = []
|
62
65
|
@transfer_setting = DRbQS::Server::TransferSetting.new(opts[:sftp_host], opts[:sftp_user], opts[:file_directory])
|
63
66
|
@config = DRbQS::Config.new
|
64
67
|
end
|
@@ -79,9 +82,10 @@ module DRbQS
|
|
79
82
|
end
|
80
83
|
private :acl_init
|
81
84
|
|
82
|
-
def hook_init(finish_exit)
|
85
|
+
def hook_init(finish_exit, shutdown_nodes)
|
83
86
|
@hook = DRbQS::Server::Hook.new
|
84
87
|
@hook.set_finish_exit { self.exit } if finish_exit
|
88
|
+
@hook.set_shutdown_unused_nodes { shutdown_unused_nodes } if shutdown_nodes
|
85
89
|
end
|
86
90
|
private :hook_init
|
87
91
|
|
@@ -112,6 +116,8 @@ module DRbQS
|
|
112
116
|
@task_generator << task_generator
|
113
117
|
end
|
114
118
|
|
119
|
+
# If current task generator waits for finish of created tasks,
|
120
|
+
# this method returns true.
|
115
121
|
def generator_waiting?
|
116
122
|
@task_generator.size > 0 && @task_generator[0].waiting?
|
117
123
|
end
|
@@ -134,6 +140,11 @@ module DRbQS
|
|
134
140
|
end
|
135
141
|
private :add_tasks_from_generator
|
136
142
|
|
143
|
+
def all_tasks_assigned?
|
144
|
+
@task_generator.empty? && @queue.empty?
|
145
|
+
end
|
146
|
+
private :all_tasks_assigned?
|
147
|
+
|
137
148
|
def set_initialization_task(task)
|
138
149
|
@message.set_initialization(task)
|
139
150
|
end
|
@@ -143,9 +154,14 @@ module DRbQS
|
|
143
154
|
@message.set_finalization(@finalization_task)
|
144
155
|
end
|
145
156
|
|
146
|
-
# +key+ is :empty_queue or :finish_exit.
|
157
|
+
# +key+ is :empty_queue, :process_data, or :finish_exit.
|
147
158
|
# &block takes self as an argument.
|
148
159
|
def add_hook(key, name = nil, &block)
|
160
|
+
if key == :process_data
|
161
|
+
if @hook.number_of_hook(:process_data) != 0
|
162
|
+
raise "Hook :process_data has already set."
|
163
|
+
end
|
164
|
+
end
|
149
165
|
@hook.add(key, name, &block)
|
150
166
|
end
|
151
167
|
|
@@ -153,26 +169,67 @@ module DRbQS
|
|
153
169
|
@hook.delete(key, name)
|
154
170
|
end
|
155
171
|
|
172
|
+
def exec_empty_queue_hook
|
173
|
+
@hook.exec(:empty_queue, self) do |name|
|
174
|
+
if @queue.empty?
|
175
|
+
@logger.info("Execute empty queue hook: #{name}.")
|
176
|
+
true
|
177
|
+
else
|
178
|
+
false
|
179
|
+
end
|
180
|
+
end
|
181
|
+
end
|
182
|
+
private :exec_empty_queue_hook
|
183
|
+
|
156
184
|
def exec_finish_hook
|
157
|
-
@
|
158
|
-
|
185
|
+
@hook.exec(:finish, self) do |name|
|
186
|
+
if !generator_waiting? && @queue.finished?
|
187
|
+
@logger.info("Execute finish hook: #{name}.")
|
188
|
+
true
|
189
|
+
else
|
190
|
+
false
|
191
|
+
end
|
192
|
+
end
|
159
193
|
end
|
160
194
|
private :exec_finish_hook
|
161
195
|
|
162
|
-
def
|
163
|
-
|
164
|
-
|
165
|
-
|
196
|
+
def exec_task_assigned_hook
|
197
|
+
@hook.exec(:task_assigned, self) do |name|
|
198
|
+
if all_tasks_assigned?
|
199
|
+
@logger.info("Execute task assigned hook: #{name}.")
|
200
|
+
true
|
201
|
+
else
|
202
|
+
false
|
203
|
+
end
|
166
204
|
end
|
205
|
+
end
|
206
|
+
private :exec_task_assigned_hook
|
207
|
+
|
208
|
+
def exec_process_data_hook
|
209
|
+
if @data_storage.size > 0
|
210
|
+
while data = @data_storage.shift
|
211
|
+
process_data(data)
|
212
|
+
end
|
213
|
+
end
|
214
|
+
end
|
215
|
+
private :exec_process_data_hook
|
216
|
+
|
217
|
+
def exec_hook
|
218
|
+
exec_process_data_hook
|
219
|
+
exec_empty_queue_hook
|
167
220
|
if !generator_waiting? || @queue.finished?
|
168
221
|
add_tasks_from_generator
|
169
222
|
end
|
170
|
-
|
171
|
-
|
172
|
-
end
|
223
|
+
exec_finish_hook
|
224
|
+
exec_task_assigned_hook
|
173
225
|
end
|
174
226
|
private :exec_hook
|
175
227
|
|
228
|
+
def shutdown_unused_nodes
|
229
|
+
@message.shutdown_unused_nodes(@queue.calculating_nodes)
|
230
|
+
end
|
231
|
+
private :shutdown_unused_nodes
|
232
|
+
|
176
233
|
def exit
|
177
234
|
if @finalization_task
|
178
235
|
@message.send_finalization
|
@@ -203,19 +260,57 @@ module DRbQS
|
|
203
260
|
end
|
204
261
|
end
|
205
262
|
|
263
|
+
# Set *args to data storage, which must be string objects.
|
264
|
+
# The data is processed by hook of :process_data.
|
265
|
+
def set_data(*args)
|
266
|
+
args.each do |s|
|
267
|
+
if String === s
|
268
|
+
@data_storage << s
|
269
|
+
else
|
270
|
+
@logger.error("Invalid data type\n#{s.inspect}")
|
271
|
+
end
|
272
|
+
end
|
273
|
+
end
|
274
|
+
|
275
|
+
def process_data(data)
|
276
|
+
@hook.exec(:process_data, self, data)
|
277
|
+
rescue => err
|
278
|
+
@logger.error("Error in processing data.") do
|
279
|
+
"#{err.to_s} (#{err.class})\n#{err.backtrace.join("\n")}"
|
280
|
+
end
|
281
|
+
end
|
282
|
+
private :process_data
|
283
|
+
|
284
|
+
def send_status_for_request
|
285
|
+
data = {
|
286
|
+
:calculating_task_number => @queue.calculating_task_number,
|
287
|
+
:finished_task_number => @queue.finished_task_number,
|
288
|
+
:stocked_task_number => @queue.stocked_task_number,
|
289
|
+
:calculating_nodes => @queue.calculating,
|
290
|
+
:generator_number => @task_generator.size
|
291
|
+
}
|
292
|
+
@message.send_status(data)
|
293
|
+
end
|
294
|
+
private :send_status_for_request
|
295
|
+
|
206
296
|
def check_message
|
207
297
|
while mes_arg = @message.get_message
|
208
298
|
mes, arg = mes_arg
|
209
299
|
case mes
|
300
|
+
when :new_data
|
301
|
+
set_data(arg)
|
210
302
|
when :exit_server
|
211
303
|
self.exit
|
212
304
|
when :request_status
|
213
|
-
|
305
|
+
send_status_for_request
|
306
|
+
when :request_history
|
307
|
+
@message.send_history(@queue.all_logs)
|
214
308
|
when :exit_after_task
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
309
|
+
@message.send_exit_after_task(arg)
|
310
|
+
when :wake_node
|
311
|
+
@message.send_wake(arg)
|
312
|
+
when :sleep_node
|
313
|
+
@message.send_sleep(arg)
|
219
314
|
when :node_error
|
220
315
|
@queue.get_accept_signal
|
221
316
|
@queue.requeue_for_deleted_node_id([arg])
|
@@ -242,58 +337,5 @@ module DRbQS
|
|
242
337
|
end
|
243
338
|
end
|
244
339
|
end
|
245
|
-
|
246
|
-
def start_profile
|
247
|
-
require 'ruby-prof'
|
248
|
-
RubyProf.start
|
249
|
-
end
|
250
|
-
private :start_profile
|
251
|
-
|
252
|
-
def finish_profile
|
253
|
-
result = RubyProf.stop
|
254
|
-
printer = RubyProf::FlatPrinter.new(result)
|
255
|
-
# printer = RubyProf::GraphPrinter.new(result)
|
256
|
-
# printer = RubyProf::CallTreePrinter.new(result)
|
257
|
-
printer.print(STDOUT)
|
258
|
-
end
|
259
|
-
private :finish_profile
|
260
|
-
|
261
|
-
def test_exec(opts = {})
|
262
|
-
first_task_generator_init
|
263
|
-
dummy_node = DRbQS::Node.new(nil, :log_file => $stdout, :log_level => opts[:log_level])
|
264
|
-
dummy_task_client = DRbQS::Node::TaskClient.new(nil, @ts[:queue], nil)
|
265
|
-
if @ts[:transfer]
|
266
|
-
dummy_node.instance_variable_set(:@transfer, DRbQS::TransferClient::Local.new(@ts[:transfer].directory))
|
267
|
-
end
|
268
|
-
num = 0
|
269
|
-
start_profile if opts[:profile]
|
270
|
-
loop do
|
271
|
-
exec_hook
|
272
|
-
if ary = dummy_task_client.get_task
|
273
|
-
task_id, marshal_obj, method_sym, args = ary
|
274
|
-
result = dummy_node.instance_eval { execute_task(marshal_obj, method_sym, args) }
|
275
|
-
@queue.exec_task_hook(self, task_id, result)
|
276
|
-
end
|
277
|
-
num += 1
|
278
|
-
if opts[:limit] && num >= opts[:limit]
|
279
|
-
break
|
280
|
-
end
|
281
|
-
end
|
282
|
-
finish_profile if opts[:profile]
|
283
|
-
if @finalization_task
|
284
|
-
args = @finalization_task.drb_args(nil)[1..-1]
|
285
|
-
dummy_node.instance_eval { execute_task(*args) }
|
286
|
-
end
|
287
|
-
exec_finish_hook
|
288
|
-
end
|
289
|
-
|
290
|
-
def test_task_generator(opts = {})
|
291
|
-
@task_generator.each_with_index do |t, i|
|
292
|
-
puts "Test task generator [#{i}]"
|
293
|
-
t.init
|
294
|
-
set_num, task_num = t.debug_all_tasks(opts)
|
295
|
-
puts "Create: task sets #{set_num}, all tasks #{task_num}"
|
296
|
-
end
|
297
|
-
end
|
298
340
|
end
|
299
341
|
end
|
@@ -6,7 +6,9 @@ module DRbQS
|
|
6
6
|
@argument_number = {}
|
7
7
|
@finish_exit = nil
|
8
8
|
set_argument_number(:empty_queue, 1)
|
9
|
+
set_argument_number(:process_data, 2)
|
9
10
|
set_argument_number(:finish, 1)
|
11
|
+
set_argument_number(:task_assigned, 1)
|
10
12
|
end
|
11
13
|
|
12
14
|
def set_argument_number(key, num)
|
@@ -41,10 +43,20 @@ module DRbQS
|
|
41
43
|
end
|
42
44
|
end
|
43
45
|
|
44
|
-
def specific_proc(key)
|
46
|
+
def specific_proc(key, &cond)
|
45
47
|
case key
|
46
48
|
when :finish
|
47
|
-
|
49
|
+
if @finish_exit
|
50
|
+
if !cond || cond.call('special:finish_exit')
|
51
|
+
@finish_exit.call
|
52
|
+
end
|
53
|
+
end
|
54
|
+
when :task_assigned
|
55
|
+
if @shutdown_unused_nodes
|
56
|
+
if !cond || cond.call('special:task_assigned')
|
57
|
+
@shutdown_unused_nodes.call
|
58
|
+
end
|
59
|
+
end
|
48
60
|
end
|
49
61
|
end
|
50
62
|
private :specific_proc
|
@@ -53,19 +65,27 @@ module DRbQS
|
|
53
65
|
@hook[key].map { |a| a[0] }
|
54
66
|
end
|
55
67
|
|
56
|
-
def exec(key, *args)
|
68
|
+
def exec(key, *args, &cond)
|
57
69
|
@hook[key].each do |ary|
|
58
|
-
ary[
|
70
|
+
if !cond || cond.call(ary[0])
|
71
|
+
ary[1].call(*args)
|
72
|
+
else
|
73
|
+
return nil
|
74
|
+
end
|
59
75
|
end
|
60
|
-
specific_proc(key)
|
76
|
+
specific_proc(key, &cond)
|
61
77
|
end
|
62
78
|
|
63
79
|
def set_finish_exit(&block)
|
64
80
|
@finish_exit = block
|
65
81
|
end
|
66
82
|
|
83
|
+
def set_shutdown_unused_nodes(&block)
|
84
|
+
@shutdown_unused_nodes = block
|
85
|
+
end
|
86
|
+
|
67
87
|
def number_of_hook(key)
|
68
|
-
@hook[key].size
|
88
|
+
@hook.has_key?(key) ? @hook[key].size : 0
|
69
89
|
end
|
70
90
|
end
|
71
91
|
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require 'drbqs/node/node'
|
2
|
+
|
3
|
+
module DRbQS
|
4
|
+
module Test
|
5
|
+
class Node < DRbQS::Node
|
6
|
+
def initialize(log_level, transfer, queue)
|
7
|
+
super(nil, :log_file => $stdout, :log_level => log_level)
|
8
|
+
@transfer = transfer
|
9
|
+
@task_client = DRbQS::Node::TaskClient.new(nil, queue, nil)
|
10
|
+
end
|
11
|
+
|
12
|
+
def server_on_same_host?
|
13
|
+
true
|
14
|
+
end
|
15
|
+
|
16
|
+
def calc
|
17
|
+
if ary = @task_client.get_task
|
18
|
+
task_id, marshal_obj, method_sym, args = ary
|
19
|
+
result = execute_task(marshal_obj, method_sym, args)
|
20
|
+
return [task_id, result]
|
21
|
+
end
|
22
|
+
nil
|
23
|
+
end
|
24
|
+
|
25
|
+
def finalize(finalization_task)
|
26
|
+
if finalization_task
|
27
|
+
args = finalization_task.drb_args(nil)[1..-1]
|
28
|
+
execute_task(*args)
|
29
|
+
end
|
30
|
+
clear_node_files
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,74 @@
|
|
1
|
+
module DRbQS
|
2
|
+
module Test
|
3
|
+
class Server < DRbQS::Server
|
4
|
+
PROF_FILE = 'drbqs_prof.txt'
|
5
|
+
|
6
|
+
def exit
|
7
|
+
throw(:exit_loop)
|
8
|
+
end
|
9
|
+
|
10
|
+
def loop_for_test(limit, profile, printer, &block)
|
11
|
+
result = { :start => Time.now }
|
12
|
+
num = 0
|
13
|
+
if profile
|
14
|
+
require 'drbqs/server/prof'
|
15
|
+
result[:profile] = FileName.create(PROF_FILE, :position => :middle)
|
16
|
+
prof = DRbQS::Prof.new(printer || :flat, result[:profile])
|
17
|
+
prof.start
|
18
|
+
end
|
19
|
+
begin
|
20
|
+
catch(:exit_loop) do
|
21
|
+
loop do
|
22
|
+
yield
|
23
|
+
if limit
|
24
|
+
num += 1
|
25
|
+
if num >= limit
|
26
|
+
exec_finish_hook
|
27
|
+
break
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
rescue Exception => err
|
33
|
+
$stdout.puts "*** Error occurs in calculation roop ***"
|
34
|
+
b = err.backtrace
|
35
|
+
$stdout.puts "#{b[0]}: #{err.to_s} (#{err.class})"
|
36
|
+
$stdout.puts b[1..-1].join("\n") if b.size > 1
|
37
|
+
end
|
38
|
+
if profile
|
39
|
+
prof.finish
|
40
|
+
end
|
41
|
+
result[:end] = Time.now
|
42
|
+
result
|
43
|
+
end
|
44
|
+
private :loop_for_test
|
45
|
+
|
46
|
+
def test_exec(opts = {})
|
47
|
+
require 'drbqs/server/test/node'
|
48
|
+
first_task_generator_init
|
49
|
+
set_file_transfer(nil)
|
50
|
+
test_node = DRbQS::Test::Node.new(@logger.level, @ts[:transfer], @ts[:queue])
|
51
|
+
n = 0
|
52
|
+
data = loop_for_test(opts[:limit], opts[:profile], opts[:printer]) do
|
53
|
+
exec_hook
|
54
|
+
if ary = test_node.calc
|
55
|
+
@queue.exec_task_hook(self, *ary)
|
56
|
+
n += 1
|
57
|
+
end
|
58
|
+
end
|
59
|
+
test_node.finalize(@finalization_task)
|
60
|
+
data[:task] = n
|
61
|
+
data
|
62
|
+
end
|
63
|
+
|
64
|
+
def test_task_generator(opts = {})
|
65
|
+
@task_generator.each_with_index do |t, i|
|
66
|
+
puts "Test task generator [#{i}]"
|
67
|
+
t.init
|
68
|
+
set_num, task_num = t.debug_all_tasks(opts)
|
69
|
+
puts "Create: task sets #{set_num}, all tasks #{task_num}"
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
@@ -0,0 +1,120 @@
|
|
1
|
+
require 'forwardable'
|
2
|
+
|
3
|
+
module DRbQS
|
4
|
+
class Setting
|
5
|
+
class InvalidLogLevel < StandardError
|
6
|
+
end
|
7
|
+
|
8
|
+
LOG_LEVEL_DEFAULT = Logger::ERROR
|
9
|
+
|
10
|
+
# A base class having options of commands.
|
11
|
+
# We must define a method 'exec' this method in a child class.
|
12
|
+
class Base
|
13
|
+
extend Forwardable
|
14
|
+
|
15
|
+
attr_reader :source
|
16
|
+
|
17
|
+
# The keys of options are :all_keys_defined, :log_level, and :daemon
|
18
|
+
def initialize(opts = {}, &block)
|
19
|
+
@source = DRbQS::Setting::Source.new(opts[:all_keys_defined])
|
20
|
+
@source.register_key(:debug, :bool => true)
|
21
|
+
if opts[:log_level]
|
22
|
+
@source.register_key(:log_level, :check => 1, :default => [Logger::ERROR])
|
23
|
+
end
|
24
|
+
if opts[:daemon]
|
25
|
+
@__daemon__ = nil
|
26
|
+
@source.register_key(:daemon, :check => 1)
|
27
|
+
end
|
28
|
+
@source.instance_eval(&block) if block_given?
|
29
|
+
@options = {}
|
30
|
+
end
|
31
|
+
|
32
|
+
def_delegator :@source, :set, :set
|
33
|
+
def_delegator :@source, :get, :get
|
34
|
+
def_delegator :@source, :clear, :clear
|
35
|
+
def_delegator :@source, :set?, :set?
|
36
|
+
def_delegator :@source, :get_first, :get_first
|
37
|
+
def_delegator :@source, :set_argument, :set_argument
|
38
|
+
def_delegator :@source, :get_argument, :get_argument
|
39
|
+
def_delegator :@source, :command_line_argument, :command_line_argument
|
40
|
+
def_delegator :@source, :default, :default
|
41
|
+
|
42
|
+
def string_for_shell
|
43
|
+
command_line_argument(true).join(" ")
|
44
|
+
end
|
45
|
+
|
46
|
+
def value
|
47
|
+
@source.value
|
48
|
+
end
|
49
|
+
|
50
|
+
def preprocess!
|
51
|
+
end
|
52
|
+
private :preprocess!
|
53
|
+
|
54
|
+
# We execute DRbQS::Setting::Base#parse! before execute 'exec'.
|
55
|
+
def parse!
|
56
|
+
preprocess!
|
57
|
+
@source.check!
|
58
|
+
$DEBUG = true if get_first(:debug)
|
59
|
+
@__daemon__ = get_first(:daemon)
|
60
|
+
parse_log_level
|
61
|
+
end
|
62
|
+
|
63
|
+
def parse_log_level
|
64
|
+
if arg = get_first(:log_level)
|
65
|
+
case arg
|
66
|
+
when /^(fatal)|(error)|(warn)|(info)|(debug)|(unknown)$/i
|
67
|
+
n = eval("Logger::#{arg.upcase}")
|
68
|
+
unless 0 <= n && n <= 5
|
69
|
+
raise DRbQS::Setting::InvalidLogLevel, "error: Invalid log level '#{arg}'"
|
70
|
+
end
|
71
|
+
when /^[0-5]$/
|
72
|
+
n = arg.to_i
|
73
|
+
when 0..5
|
74
|
+
n = arg
|
75
|
+
else
|
76
|
+
raise DRbQS::Setting::InvalidLogLevel, "error: Invalid log level '#{arg}'"
|
77
|
+
end
|
78
|
+
@options[:log_level] = n
|
79
|
+
end
|
80
|
+
end
|
81
|
+
private :parse_log_level
|
82
|
+
|
83
|
+
def daemon_start(output, &block)
|
84
|
+
Process.daemon(true)
|
85
|
+
begin
|
86
|
+
$stdout = Kernel.open(output, 'w')
|
87
|
+
$stderr = $stdout
|
88
|
+
begin
|
89
|
+
yield
|
90
|
+
rescue SystemExit
|
91
|
+
return true
|
92
|
+
end
|
93
|
+
rescue Exception => err
|
94
|
+
output_error(err)
|
95
|
+
ensure
|
96
|
+
$stdout.close
|
97
|
+
end
|
98
|
+
end
|
99
|
+
private :daemon_start
|
100
|
+
|
101
|
+
def exec_as_daemon(&block)
|
102
|
+
if @__daemon__
|
103
|
+
@__daemon__ = FileName.create(@__daemon__, :position => :middle, :type => :time, :directory => :parent)
|
104
|
+
daemon_start(@__daemon__) do
|
105
|
+
@__daemon__ = nil
|
106
|
+
if block_given?
|
107
|
+
yield
|
108
|
+
else
|
109
|
+
exec($stdout)
|
110
|
+
end
|
111
|
+
end
|
112
|
+
true
|
113
|
+
else
|
114
|
+
nil
|
115
|
+
end
|
116
|
+
end
|
117
|
+
private :exec_as_daemon
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|