drbqs 0.0.19 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (77) hide show
  1. checksums.yaml +7 -0
  2. data/docs/TestProfiler.md +30 -0
  3. data/drbqs.gemspec +2 -1
  4. data/{example → examples}/README.md +0 -0
  5. data/{example → examples}/command/server_def.rb +1 -1
  6. data/{example → examples}/error_server/error.rb +0 -0
  7. data/{example → examples}/error_server/server_def.rb +0 -0
  8. data/{example → examples}/error_task/error.rb +0 -0
  9. data/{example → examples}/error_task/server_def.rb +1 -1
  10. data/examples/execute/README.md +7 -0
  11. data/examples/execute/execute.rb +10 -0
  12. data/examples/execute/server.rb +27 -0
  13. data/{example/sum → examples/execute}/sum.rb +0 -0
  14. data/{example → examples}/group/execute.rb +5 -2
  15. data/{example → examples}/group/server.rb +0 -0
  16. data/{example → examples}/group/sum.rb +0 -0
  17. data/{example → examples}/mandelbrot/README.md +0 -0
  18. data/{example → examples}/mandelbrot/execute.rb +4 -1
  19. data/{example → examples}/mandelbrot/mandelbrot.rb +0 -0
  20. data/{example → examples}/mandelbrot/server.rb +0 -0
  21. data/examples/server/server.rb +20 -0
  22. data/{example → examples}/simple/README.md +0 -0
  23. data/{example → examples}/simple/execute.rb +0 -0
  24. data/{example → examples}/simple/server.rb +0 -0
  25. data/{example → examples}/simple/task.rb +0 -0
  26. data/{example → examples}/sum/server_def.rb +5 -1
  27. data/examples/sum/sum.rb +10 -0
  28. data/{example → examples}/sum2/execute_def.rb +0 -0
  29. data/{example → examples}/sum2/server_def.rb +3 -4
  30. data/{example → examples}/sum2/sum.rb +0 -0
  31. data/{example → examples}/transfer/file.rb +0 -0
  32. data/{example → examples}/transfer/server_def.rb +0 -0
  33. data/lib/drbqs.rb +5 -0
  34. data/lib/drbqs/command_line/command_execute.rb +1 -0
  35. data/lib/drbqs/command_line/command_server.rb +1 -1
  36. data/lib/drbqs/config/process_list.rb +9 -7
  37. data/lib/drbqs/execute/process_define.rb +109 -18
  38. data/lib/drbqs/execute/register.rb +41 -33
  39. data/lib/drbqs/ext/task/command_task.rb +20 -17
  40. data/lib/drbqs/node/connection.rb +1 -2
  41. data/lib/drbqs/node/node.rb +3 -4
  42. data/lib/drbqs/server/server.rb +9 -3
  43. data/lib/drbqs/setting/base.rb +1 -0
  44. data/lib/drbqs/setting/data_container.rb +2 -2
  45. data/lib/drbqs/setting/execute.rb +9 -2
  46. data/lib/drbqs/setting/node.rb +7 -1
  47. data/lib/drbqs/setting/server.rb +4 -1
  48. data/lib/drbqs/task/registrar.rb +1 -2
  49. data/lib/drbqs/utility/misc.rb +6 -1
  50. data/lib/drbqs/utility/temporary.rb +27 -34
  51. data/lib/drbqs/version.rb +1 -1
  52. data/lib/drbqs/worker/worker_process_set.rb +3 -1
  53. data/spec/command_line/command_base_spec.rb +2 -2
  54. data/spec/config/config_spec.rb +5 -4
  55. data/spec/config/ssh_host_spec.rb +1 -1
  56. data/spec/execute/process_define_spec.rb +65 -18
  57. data/spec/execute/register_spec.rb +31 -9
  58. data/spec/ext/task/command_task_spec.rb +3 -5
  59. data/spec/integration_test/09_server_process_data_spec.rb +1 -1
  60. data/spec/node/node_spec.rb +3 -3
  61. data/spec/node/task_client_spec.rb +10 -10
  62. data/spec/server/history_spec.rb +22 -10
  63. data/spec/server/queue_spec.rb +11 -11
  64. data/spec/server/server_spec.rb +2 -2
  65. data/spec/server/transfer_setting_spec.rb +1 -1
  66. data/spec/setting/source_spec.rb +11 -10
  67. data/spec/task/task_spec.rb +5 -5
  68. data/spec/utility/misc_spec.rb +1 -1
  69. data/spec/utility/temporary_spec.rb +1 -7
  70. data/spec/utility/transfer/transfer_client_connect_spec.rb +4 -4
  71. data/spec/utility/transfer/transfer_file_list_spec.rb +2 -2
  72. data/spec/utility/transfer/transfer_spec.rb +23 -8
  73. metadata +108 -70
  74. data/example/execute/execute.rb +0 -41
  75. data/example/execute/server.rb +0 -14
  76. data/example/execute/task.rb +0 -0
  77. data/example/server/server.rb +0 -11
@@ -18,6 +18,7 @@ module DRbQS
18
18
  def __register__(type, setting, name, template, args, &block)
19
19
  ary = [name.intern, { :type => type.intern, :template => template, :args => args }]
20
20
  type = type.to_s
21
+ # Note that if type is :server, then args[0] is hostname
21
22
  case block.arity
22
23
  when 2
23
24
  if DRbQS::Setting::SSH === setting
@@ -33,6 +34,10 @@ module DRbQS
33
34
  end
34
35
  ary[1][:ssh] = true
35
36
  ary[1][:setting] = ssh_setting
37
+
38
+ if type == "server" && !template && !args[0]
39
+ raise ArgumentError, "No hostname of SSH server"
40
+ end
36
41
  when 1
37
42
  if DRbQS::Setting::SSH === setting
38
43
  raise ArgumentError, "Inherited definition is over ssh."
@@ -40,6 +45,7 @@ module DRbQS
40
45
  yield(setting.value)
41
46
  ary[1][:ssh] = false
42
47
  ary[1][:setting] = setting
48
+ ary[1][:unix_domain_socket] = (!template && !args[0])
43
49
  else
44
50
  raise ArgumentError, "Block must take one or two arguments."
45
51
  end
@@ -89,12 +95,21 @@ module DRbQS
89
95
  # If we omit the 'connect' method then the program tries to connect
90
96
  # the name specified as first argument.
91
97
  #
92
- # @param [Symbol,String] name Server name
93
- # @param [Hash] opts The options of server
94
- # @option opts [Boolean] :template Template for other servers to load, not actual server
95
- # @option opts [Symbol] :load Inherit definition of other server
98
+ # @overload server(name, hostname, opts = {})
99
+ # @param [Symbol,String] name Server name
100
+ # @param [Symbol,String] hostname Hostname of server to access over SSH
101
+ # @param [Hash] opts The options of server
102
+ # @option opts [Boolean] :template Template for other servers to load, not actual server
103
+ # @option opts [Symbol] :load Inherit definition of other server
104
+ #
105
+ # @overload server(name, opts = {})
106
+ # If hostname is omitted, the server uses UNIX domain socket and executes some nodes together.
107
+ # @param [Symbol,String] name Server name
108
+ # @param [Hash] opts The options of server
109
+ # @option opts [Boolean] :template Template for other servers to load, not actual server
110
+ # @option opts [Symbol] :load Inherit definition of other server
96
111
  #
97
- # @example A server on localhost
112
+ # @example A server on localhost (Connections from nodes is over SSH)
98
113
  # server :server_local, "example.com" do |srv|
99
114
  # srv.load "server_definition.rb"
100
115
  # srv.acl "/path/to/acl"
@@ -104,7 +119,7 @@ module DRbQS
104
119
  # srv.sftp_host "example.com"
105
120
  # end
106
121
  #
107
- # @example A server over ssh
122
+ # @example A server executed over SSH
108
123
  # server :server_ssh, "example.co.jp" do |srv, ssh|
109
124
  # srv.load "server_definition.rb"
110
125
  # srv.acl "/path/to/acl"
@@ -120,36 +135,28 @@ module DRbQS
120
135
  # ssh.output "/path/to/output"
121
136
  # ssh.nice 10
122
137
  # end
138
+ #
139
+ # @example A server on localhost that uses UNIX domain socket (No node on other computer)
140
+ # server :server_unix_domain_socket do |srv|
141
+ # srv.load "server_definition.rb"
142
+ # srv.execute_node 4
143
+ # end
123
144
  def server(name, *args, &block)
145
+ unless block_given?
146
+ raise ArgumentError, "Block to define settings is not given."
147
+ end
124
148
  name = name.intern
125
149
  if ind = @__server__.index { |n, data| name == n }
126
150
  old_data = @__server__.delete_at(ind)
127
151
  else
128
152
  old_data = nil
129
153
  end
130
- unless block_given?
131
- raise ArgumentError, "Block to define settings is not given."
132
- end
133
- case args.size
134
- when 2
135
- hostname = args[0]
136
- opts = args[1]
137
- unless Hash === opts
138
- raise ArgumentError, "Options must be hash."
139
- end
140
- when 1
141
- if Hash === args[0]
142
- hostname = nil
143
- opts = args[0]
144
- else
145
- hostname = args[0]
146
- opts = {}
147
- end
148
- else
149
- unless old_data
150
- raise ArgumentError, "Invalid argument size."
151
- end
154
+ opts = args.extract_options!
155
+ opts.assert_valid_keys(:template, :load)
156
+ if args.size > 1
157
+ raise ArgumentError, "Invalid number of arguments."
152
158
  end
159
+ hostname = args[0]
153
160
  if old_data
154
161
  if opts[:load]
155
162
  raise ArgumentError, "Can not set both reconfiguring and loading."
@@ -159,9 +166,6 @@ module DRbQS
159
166
  else
160
167
  load_def = opts[:load]
161
168
  end
162
- if !opts[:template] && !hostname
163
- raise ArgumentError, "Definition of server '#{name}' needs hostname."
164
- end
165
169
  __register_server__(opts[:template], name, load_def, hostname, &block)
166
170
  end
167
171
 
@@ -203,6 +207,7 @@ module DRbQS
203
207
  # @example Node group
204
208
  # node :node_group, :group => [:node_local, :node_ssh]
205
209
  def node(name, opts = {}, &block)
210
+ opts.assert_valid_keys(:template, :load, :group)
206
211
  name = name.intern
207
212
  load_def = opts[:load]
208
213
  if ind = @__node__.index { |n, data| name == n }
@@ -233,7 +238,7 @@ module DRbQS
233
238
  end
234
239
  end
235
240
 
236
- # @param [Array] *args Symbols of servers
241
+ # @param [Array] args Symbols of servers
237
242
  # @example Clear server definitions
238
243
  # clear_server :server1, :server2
239
244
  def clear_server(*args)
@@ -244,7 +249,7 @@ module DRbQS
244
249
  end
245
250
  end
246
251
 
247
- # @param [Array] *args Symbols of nodes
252
+ # @param [Array] args Symbols of nodes
248
253
  # @example Clear node definitions
249
254
  # clear_node :node1, :node2
250
255
  def clear_node(*args)
@@ -259,10 +264,12 @@ module DRbQS
259
264
  # @param [Hash] val the pair of key and value
260
265
  # @option val [Fixnum] :port Port number of a server
261
266
  # @option val [Symbol] :server Server executed by default
267
+ # @option val [Array] :node Nodes executed by default if server has no node
262
268
  # @option val [String] :log Path of log of a server and nods on localhost
263
269
  # @example Set default value
264
270
  # default :port => 13456, :server => :server_local, :log => "/tmp/drbqs_execute_log"
265
271
  def default(val = {})
272
+ val.assert_valid_keys(:port, :server, :node, :log)
266
273
  val.delete_if { |key, v| !v }
267
274
  if val[:server]
268
275
  val[:server] = val[:server].intern
@@ -290,6 +297,7 @@ module DRbQS
290
297
  # @example Set usage
291
298
  # usage :message => 'Calculate some value', :server => 'server.rb'
292
299
  def usage(opts = {})
300
+ opts.assert_valid_keys(:message, :server)
293
301
  @__usage__.merge!(opts)
294
302
  end
295
303
 
@@ -4,26 +4,23 @@ module DRbQS
4
4
 
5
5
  # Execute a command and transfer files if needed.
6
6
  class CommandExecute
7
-
8
- # :transfer String or Array
9
- # :compress true or false
10
- def initialize(cmd, opts = {})
11
- @cmd = cmd
12
- unless (Array === @cmd || String === @cmd)
13
- raise ArgumentError, "Invalid command: #{@cmd.inspect}"
7
+ def initialize(cmds, opts = {})
8
+ opts.assert_valid_keys(:transfer, :compress)
9
+ @cmds = cmds
10
+ if String === @cmds
11
+ @cmds = [@cmds]
12
+ elsif !(Array === @cmds)
13
+ raise ArgumentError, "Invalid command: #{@cmds.inspect}"
14
14
  end
15
15
  @transfer = opts[:transfer]
16
16
  @compress = opts[:compress]
17
17
  end
18
18
 
19
19
  def exec
20
- case @cmd
21
- when Array
22
- @cmd.each { |c| system(c) }
23
- when String
24
- system(@cmd)
20
+ exit_status_ary = @cmds.map do |cmd|
21
+ system(cmd)
22
+ $?.exitstatus
25
23
  end
26
- exit_status = $?.exitstatus
27
24
  if @transfer
28
25
  if @transfer.respond_to?(:each)
29
26
  @transfer.each { |path| DRbQS::Transfer.enqueue(path, :compress => @compress) }
@@ -31,13 +28,19 @@ module DRbQS
31
28
  DRbQS::Transfer.enqueue(@transfer, :compress => @compress)
32
29
  end
33
30
  end
34
- exit_status
31
+ exit_status_ary
35
32
  end
36
33
  end
37
34
 
38
- # &hook takes a server instance and exit number of command.
39
- def initialize(cmd, opts = {}, &hook)
40
- super(DRbQS::CommandTask::CommandExecute.new(cmd, opts), :exec, &hook)
35
+ # @override initialize(*cmds, opts = {}, &hook)
36
+ # @param [Array] cmds An array of commands which are string or array, that is, arguments of the method 'system'.
37
+ # @param [Hash] opts Hash of options
38
+ # @param [Proc] hook Block same as that of DRbQS::Task object, which takes a server instance and an array of exit statuses.
39
+ # @option opts [String,Array] :transfer Paths to be transfered after finish of commands
40
+ # @option opts [boolean] :compress Compress files before transfering or not
41
+ def initialize(*args, &hook)
42
+ opts = args.extract_options!
43
+ super(DRbQS::CommandTask::CommandExecute.new(args, opts), :exec, &hook)
41
44
  end
42
45
  end
43
46
  end
@@ -12,8 +12,7 @@ module DRbQS
12
12
  end
13
13
 
14
14
  def create_id_string
15
- t = Time.now
16
- sprintf("#{Socket.gethostname}:%d", Process.pid)
15
+ "#{Socket.gethostname}:#{Process.pid}:#{Time.now.strftime('%s')}"
17
16
  end
18
17
  private :create_id_string
19
18
 
@@ -1,5 +1,4 @@
1
1
  require 'drbqs/task/task'
2
- require 'drbqs/utility/temporary'
3
2
  require 'drbqs/utility/transfer/transfer_client'
4
3
  require 'drbqs/node/connection'
5
4
  require 'drbqs/node/task_client'
@@ -18,7 +17,7 @@ module DRbQS
18
17
  WAIT_NEW_TASK_TIME = 1
19
18
  SAME_HOST_GROUP = :local
20
19
 
21
- # @param [String] acces_uri Set the uri of server
20
+ # @param [String] access_uri Set the uri of server
22
21
  # @param [Hash] opts Options of a node
23
22
  # @option opts [Fixnum] :process Number of worker processes
24
23
  # @option opts [Array] :group An array of group symbols
@@ -62,7 +61,7 @@ module DRbQS
62
61
  transfer_file(files)
63
62
  end
64
63
  if subdir = result_hash[:tmp]
65
- FileUtils.rm_r(result_hash[:tmp])
64
+ FileUtils.rm_r(subdir)
66
65
  end
67
66
  @task_client.queue_result(task_id, result_hash[:result])
68
67
  end
@@ -223,7 +222,7 @@ module DRbQS
223
222
  private :send_task_to_worker
224
223
 
225
224
  def clear_node_files
226
- DRbQS::Temporary.delete_all
225
+ DRbQS::Temporary.delete
227
226
  @config.list.node.delete(Process.pid)
228
227
  end
229
228
  private :clear_node_files
@@ -161,12 +161,12 @@ module DRbQS
161
161
  end
162
162
  private :all_tasks_assigned?
163
163
 
164
- # @param [DRbQS::task] task
164
+ # @param [Array] tasks An array of DRbQS::task objects, which are executed at initialization
165
165
  def set_initialization_task(*tasks)
166
166
  @message.set_initialization_tasks(tasks)
167
167
  end
168
168
 
169
- # @param [DRbQS::task] task
169
+ # @param [Array] tasks An array of DRbQS::task objects, which are executed at initialization
170
170
  def set_finalization_task(*tasks)
171
171
  @finalization_task.concat(tasks)
172
172
  end
@@ -175,10 +175,10 @@ module DRbQS
175
175
  # @note When we set both :empty_queue and task generators,
176
176
  # hook of :empty_queue is prior to task generators.
177
177
  # @param [:empty_queue,:process_data,:finish] key Set the type of hook.
178
+ # @param [Proc] block The block is obligatory and takes server itself as an argument.
178
179
  # @option opts [Fixnum] :repeat If we execute the hook specified times then the hook is deleted.
179
180
  # If the value is nil, the hook is repeated without limit.
180
181
  # @option opts [String] :name Name of the hook. If the value is nil then the name is automatically created.
181
- # @param [Proc] &block block is obligatory and takes server itself as an argument.
182
182
  def add_hook(key, opts = {}, &block)
183
183
  if key == :process_data
184
184
  if @hook.number_of_hook(:process_data) != 0
@@ -395,6 +395,11 @@ module DRbQS
395
395
  end
396
396
  private :first_task_generator_init
397
397
 
398
+ def clear_server_files
399
+ DRbQS::Temporary.delete
400
+ end
401
+ private :clear_server_files
402
+
398
403
  def wait
399
404
  first_task_generator_init
400
405
  loop do
@@ -407,6 +412,7 @@ module DRbQS
407
412
  sleep(WAIT_TIME_NEW_RESULT)
408
413
  end
409
414
  end
415
+ clear_server_files
410
416
  end
411
417
  end
412
418
  end
@@ -10,6 +10,7 @@ module DRbQS
10
10
  # A base class having options of commands.
11
11
  # We must define a method 'exec' this method in a child class.
12
12
  class Base
13
+ include DRbQS::Misc
13
14
  extend Forwardable
14
15
 
15
16
  attr_reader :source
@@ -3,7 +3,7 @@ module DRbQS
3
3
  class Source
4
4
  class DataContainer < BasicObject
5
5
  attr_accessor :argument
6
- attr_reader :__data__
6
+ attr_reader :__data__, :__array__
7
7
 
8
8
  def initialize(array_class)
9
9
  @argument = []
@@ -27,7 +27,7 @@ module DRbQS
27
27
  end
28
28
 
29
29
  def self.clone_container(obj)
30
- cl = DRbQS::Setting::Source::DataContainer.new(Array)
30
+ cl = DRbQS::Setting::Source::DataContainer.new(obj.__array__)
31
31
  cl.argument = obj.argument.clone
32
32
  obj.__data__.each do |key, val|
33
33
  cl.__data__[key] = val.clone
@@ -10,7 +10,7 @@ module DRbQS
10
10
  [:port, :server, :node].each do |key|
11
11
  register_key(key, :check => 1)
12
12
  end
13
- [:no_server, :no_node, :information, :help].each do |key|
13
+ [:no_server, :no_node, :wait_server_finish, :information, :help].each do |key|
14
14
  register_key(key, :bool => true)
15
15
  end
16
16
  set_argument_condition(:<=, 1)
@@ -43,6 +43,7 @@ module DRbQS
43
43
  else
44
44
  @mode = nil
45
45
  end
46
+ @wait_server_finish = set?(:wait_server_finish)
46
47
  if @mode != :help && !@definition
47
48
  raise DRbQS::Setting::InvalidArgument, "Definition file must be specified."
48
49
  end
@@ -50,7 +51,10 @@ module DRbQS
50
51
 
51
52
  def exec(io = nil)
52
53
  process_def = DRbQS::ProcessDefinition.new(@server, @node, @port, io)
53
- process_def.load(@definition) if @definition
54
+ if @definition
55
+ process_def.load(@definition)
56
+ process_def.test_consistency
57
+ end
54
58
  case @mode
55
59
  when :help
56
60
  io.puts process_def.usage if io
@@ -63,6 +67,9 @@ module DRbQS
63
67
  unless @no_node
64
68
  process_def.execute_node
65
69
  end
70
+ if !@no_server && @wait_server_finish
71
+ process_def.wait_server_finish
72
+ end
66
73
  end
67
74
  true
68
75
  end
@@ -69,7 +69,12 @@ module DRbQS
69
69
  private :parse_group
70
70
 
71
71
  def exec(io = nil)
72
- return true if exec_as_daemon
72
+ if @__daemon__
73
+ fork do
74
+ exec_as_daemon
75
+ end
76
+ return true
77
+ end
73
78
 
74
79
  @options[:load].each do |path|
75
80
  io.puts "load #{path}" if io
@@ -80,6 +85,7 @@ module DRbQS
80
85
  end
81
86
 
82
87
  if io
88
+ io.puts "PID: #{Process.pid}"
83
89
  io.puts "Connect to #{@uri}"
84
90
  io.puts "Execute #{@process_num} processes"
85
91
  end
@@ -25,9 +25,12 @@ module DRbQS
25
25
 
26
26
  def parse_test
27
27
  @test_opts[:profile] = get(:profile)
28
- @test_opts[:printer] = get_first(:printer) do |val|
28
+ @test_opts[:printer] = get_first(:profile_printer) do |val|
29
29
  val.intern
30
30
  end
31
+ if @test_opts[:printer] && !@test_opts[:profile]
32
+ @test_opts[:profile] = true
33
+ end
31
34
  if test = get_first(:test)
32
35
  @command_type = "test_#{test.to_s}"
33
36
  end
@@ -11,8 +11,7 @@ module DRbQS
11
11
  end
12
12
 
13
13
  # Add tasks to server.
14
- # @param [DRbQS::Task] arg Add an ojbect of DRbQS::Task.
15
- # @param [Array] arg Add all elements of an array of objects of DRbQS::Task.
14
+ # @param [DRbQS::Task,Array] arg DRbQS::Task object or array of DRbQS::Task objects, which is added to pool of tasks
16
15
  def add(arg)
17
16
  case arg
18
17
  when DRbQS::Task
@@ -16,6 +16,11 @@ module DRbQS
16
16
  end
17
17
  end
18
18
 
19
+ def uri_drbunix(path)
20
+ "drbunix:#{path}"
21
+ end
22
+ module_function :uri_drbunix
23
+
19
24
  # @param [Hash] opts The arguments of URI of server
20
25
  # @option opts [Fixnum] :port Port number of a server
21
26
  # @option opts [String] :host Hostname of a server
@@ -33,7 +38,7 @@ module DRbQS
33
38
  elsif File.exist?(path)
34
39
  raise ArgumentError, "File #{path} already exists."
35
40
  end
36
- "drbunix:#{path}"
41
+ uri_drbunix(path)
37
42
  end
38
43
  end
39
44
  module_function :create_uri