drbqs 0.0.19 → 0.1.0

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 (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