drbqs 0.0.14 → 0.0.15

Sign up to get free protection for your applications and to get access to all the features.
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