drbqs 0.0.14 → 0.0.15

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.
Files changed (101) hide show
  1. data/VERSION +1 -1
  2. data/bin/drbqs-execute +6 -0
  3. data/bin/drbqs-manage +2 -2
  4. data/bin/drbqs-node +2 -2
  5. data/bin/drbqs-server +2 -2
  6. data/bin/drbqs-ssh +2 -2
  7. data/drbqs.gemspec +53 -16
  8. data/example/error_server/error.rb +6 -0
  9. data/example/error_server/server_def.rb +7 -0
  10. data/example/{error → error_task}/error.rb +0 -0
  11. data/example/{error → error_task}/server_def.rb +0 -0
  12. data/example/sum2/execute_def.rb +27 -0
  13. data/lib/drbqs/command_line/argument.rb +29 -0
  14. data/lib/drbqs/command_line/command_base.rb +81 -0
  15. data/lib/drbqs/command_line/command_execute.rb +33 -0
  16. data/lib/drbqs/command_line/command_line.rb +19 -0
  17. data/lib/drbqs/command_line/command_manage.rb +34 -0
  18. data/lib/drbqs/command_line/command_node.rb +26 -0
  19. data/lib/drbqs/command_line/command_server.rb +41 -0
  20. data/lib/drbqs/command_line/command_ssh.rb +51 -0
  21. data/lib/drbqs/command_line/option_setting.rb +42 -0
  22. data/lib/drbqs/execute/process_define.rb +213 -0
  23. data/lib/drbqs/execute/register.rb +147 -0
  24. data/lib/drbqs/{utility → execute}/server_define.rb +7 -14
  25. data/lib/drbqs/manage/execute_node.rb +4 -2
  26. data/lib/drbqs/manage/manage.rb +23 -16
  27. data/lib/drbqs/manage/send_signal.rb +31 -4
  28. data/lib/drbqs/manage/ssh_execute.rb +50 -6
  29. data/lib/drbqs/manage/ssh_shell.rb +95 -50
  30. data/lib/drbqs/node/connection.rb +1 -1
  31. data/lib/drbqs/node/node.rb +67 -17
  32. data/lib/drbqs/node/state.rb +109 -0
  33. data/lib/drbqs/node/task_client.rb +7 -7
  34. data/lib/drbqs/server/history.rb +16 -0
  35. data/lib/drbqs/server/message.rb +80 -15
  36. data/lib/drbqs/server/node_list.rb +16 -3
  37. data/lib/drbqs/server/prof.rb +48 -0
  38. data/lib/drbqs/server/queue.rb +20 -2
  39. data/lib/drbqs/server/server.rb +112 -70
  40. data/lib/drbqs/server/server_hook.rb +26 -6
  41. data/lib/drbqs/server/test/node.rb +34 -0
  42. data/lib/drbqs/server/test/server.rb +74 -0
  43. data/lib/drbqs/setting/base.rb +120 -0
  44. data/lib/drbqs/setting/data_container.rb +39 -0
  45. data/lib/drbqs/setting/execute.rb +71 -0
  46. data/lib/drbqs/setting/manage.rb +163 -0
  47. data/lib/drbqs/setting/node.rb +84 -0
  48. data/lib/drbqs/setting/server.rb +230 -0
  49. data/lib/drbqs/setting/setting.rb +14 -0
  50. data/lib/drbqs/setting/source.rb +220 -0
  51. data/lib/drbqs/setting/ssh.rb +165 -0
  52. data/lib/drbqs/task/task_generator.rb +4 -2
  53. data/lib/drbqs/utility/misc.rb +15 -1
  54. data/lib/drbqs/utility/temporary.rb +4 -2
  55. data/lib/drbqs.rb +3 -2
  56. data/spec/command_line/command_base_spec.rb +47 -0
  57. data/spec/{utility/command_line → command_line}/commands_spec.rb +3 -3
  58. data/spec/command_line/option_setting_spec.rb +29 -0
  59. data/spec/execute/def/execute1.rb +24 -0
  60. data/spec/execute/def/no_def.rb +2 -0
  61. data/spec/execute/process_define_spec.rb +167 -0
  62. data/spec/execute/register_spec.rb +77 -0
  63. data/spec/{utility → execute}/server_define_spec.rb +0 -0
  64. data/spec/integration_test/01_basic_usage_spec.rb +1 -1
  65. data/spec/integration_test/02_use_generator_spec.rb +1 -1
  66. data/spec/integration_test/03_use_temporary_file_spec.rb +1 -1
  67. data/spec/integration_test/04_use_unix_domain_spec.rb +1 -1
  68. data/spec/integration_test/05_server_exit_signal_spec.rb +1 -1
  69. data/spec/integration_test/06_node_exit_after_task_spec.rb +1 -1
  70. data/spec/integration_test/07_command_server_with_node_spec.rb +19 -16
  71. data/spec/integration_test/08_shutdown_unused_nodes_spec.rb +38 -0
  72. data/spec/integration_test/09_server_process_data_spec.rb +74 -0
  73. data/spec/integration_test/10_test_server_spec.rb +18 -0
  74. data/spec/integration_test/definition/task_obj_definition.rb +14 -0
  75. data/spec/manage/send_signal_spec.rb +8 -0
  76. data/spec/manage/ssh_shell_spec.rb +1 -1
  77. data/spec/node/state_spec.rb +148 -0
  78. data/spec/node/task_client_spec.rb +15 -0
  79. data/spec/server/history_spec.rb +51 -20
  80. data/spec/server/message_spec.rb +7 -2
  81. data/spec/server/node_list_spec.rb +1 -1
  82. data/spec/server/queue_spec.rb +93 -4
  83. data/spec/server/server_hook_spec.rb +62 -0
  84. data/spec/setting/base_spec.rb +35 -0
  85. data/spec/setting/data_container_spec.rb +92 -0
  86. data/spec/setting/execute_spec.rb +51 -0
  87. data/spec/setting/manage_spec.rb +63 -0
  88. data/spec/setting/node_spec.rb +43 -0
  89. data/spec/setting/server_spec.rb +46 -0
  90. data/spec/setting/source_spec.rb +245 -0
  91. data/spec/spec_helper.rb +17 -10
  92. data/spec/utility/argument_spec.rb +7 -7
  93. metadata +179 -146
  94. data/lib/drbqs/utility/argument.rb +0 -27
  95. data/lib/drbqs/utility/command_line/command_base.rb +0 -27
  96. data/lib/drbqs/utility/command_line/command_manage.rb +0 -121
  97. data/lib/drbqs/utility/command_line/command_node.rb +0 -103
  98. data/lib/drbqs/utility/command_line/command_server.rb +0 -165
  99. data/lib/drbqs/utility/command_line/command_ssh.rb +0 -126
  100. data/lib/drbqs/utility/command_line.rb +0 -15
  101. 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
- @history.set(id, :disconnect)
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
@@ -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::History.new
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
- @cache.size - calculating_task_number == 0
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
@@ -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
- @logger.info("Execute finish hook.")
158
- @hook.exec(:finish, self)
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 exec_hook
163
- if @queue.empty?
164
- @logger.info("Execute empty queue hook.")
165
- @hook.exec(:empty_queue, self)
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
- if !generator_waiting? && @queue.finished?
171
- exec_finish_hook
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
- @message.send_status(@queue.calculating)
305
+ send_status_for_request
306
+ when :request_history
307
+ @message.send_history(@queue.all_logs)
214
308
  when :exit_after_task
215
- node_id = arg
216
- if @message.node_exist?(node_id)
217
- @message.send_exit_after_task(node_id)
218
- end
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
- @finish_exit.call if @finish_exit
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[1].call(*args)
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