drbqs 0.0.15 → 0.0.16

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 (96) hide show
  1. data/.document +3 -0
  2. data/README.md +137 -128
  3. data/VERSION +1 -1
  4. data/docs/FormatExecute.md +119 -0
  5. data/docs/GettingStarted.md +242 -0
  6. data/drbqs.gemspec +36 -13
  7. data/example/command/server_def.rb +4 -5
  8. data/example/execute/execute.rb +41 -0
  9. data/example/execute/server.rb +14 -0
  10. data/example/execute/task.rb +0 -0
  11. data/example/mandelbrot/README.md +15 -0
  12. data/example/mandelbrot/execute.rb +10 -0
  13. data/example/mandelbrot/mandelbrot.rb +56 -0
  14. data/example/mandelbrot/server.rb +49 -0
  15. data/example/server/server.rb +3 -6
  16. data/example/simple/README.md +18 -0
  17. data/example/simple/execute.rb +11 -0
  18. data/example/simple/server.rb +8 -0
  19. data/example/simple/task.rb +11 -0
  20. data/example/sum/server_def.rb +1 -1
  21. data/example/sum2/execute_def.rb +21 -8
  22. data/example/sum2/server_def.rb +8 -7
  23. data/example/transfer/file.rb +42 -8
  24. data/example/transfer/server_def.rb +43 -9
  25. data/lib/drbqs.rb +1 -1
  26. data/lib/drbqs/command_line/command_execute.rb +3 -3
  27. data/lib/drbqs/command_line/command_line.rb +1 -1
  28. data/lib/drbqs/execute/execute_node.rb +50 -0
  29. data/lib/drbqs/execute/process_define.rb +102 -54
  30. data/lib/drbqs/execute/register.rb +241 -87
  31. data/lib/drbqs/execute/server_define.rb +69 -58
  32. data/lib/drbqs/ext/task.rb +2 -0
  33. data/lib/drbqs/ext/task/command_task.rb +43 -0
  34. data/lib/drbqs/manage/manage.rb +5 -4
  35. data/lib/drbqs/manage/ssh_shell.rb +2 -8
  36. data/lib/drbqs/node/connection.rb +1 -1
  37. data/lib/drbqs/node/node.rb +8 -14
  38. data/lib/drbqs/node/task_client.rb +1 -1
  39. data/lib/drbqs/server/history.rb +5 -1
  40. data/lib/drbqs/server/message.rb +7 -34
  41. data/lib/drbqs/server/queue.rb +14 -2
  42. data/lib/drbqs/server/server.rb +86 -43
  43. data/lib/drbqs/server/server_hook.rb +3 -0
  44. data/lib/drbqs/server/test/node.rb +1 -1
  45. data/lib/drbqs/server/test/prof.rb +50 -0
  46. data/lib/drbqs/server/test/server.rb +2 -2
  47. data/lib/drbqs/server/transfer_setting.rb +23 -11
  48. data/lib/drbqs/setting/base.rb +15 -0
  49. data/lib/drbqs/setting/data_container.rb +1 -1
  50. data/lib/drbqs/setting/execute.rb +3 -3
  51. data/lib/drbqs/setting/node.rb +1 -1
  52. data/lib/drbqs/setting/server.rb +2 -2
  53. data/lib/drbqs/task/registrar.rb +39 -0
  54. data/lib/drbqs/task/task.rb +139 -59
  55. data/lib/drbqs/task/task_generator.rb +93 -116
  56. data/lib/drbqs/utility/misc.rb +15 -10
  57. data/lib/drbqs/utility/temporary.rb +7 -2
  58. data/lib/drbqs/utility/transfer/transfer.rb +81 -0
  59. data/lib/drbqs/utility/transfer/transfer_client.rb +68 -69
  60. data/lib/drbqs/utility/transfer/transfer_client_connect.rb +83 -0
  61. data/lib/drbqs/utility/transfer/transfer_file_list.rb +40 -0
  62. data/spec/execute/def/execute1.rb +4 -4
  63. data/spec/execute/def/execute2.rb +24 -0
  64. data/spec/execute/process_define_spec.rb +43 -6
  65. data/spec/execute/register_spec.rb +403 -9
  66. data/spec/execute/server_define_spec.rb +1 -1
  67. data/spec/ext/task/command_task_spec.rb +16 -0
  68. data/spec/integration_test/01_basic_usage_spec.rb +1 -1
  69. data/spec/integration_test/02_use_generator_spec.rb +2 -2
  70. data/spec/integration_test/04_use_unix_domain_spec.rb +1 -1
  71. data/spec/integration_test/05_server_exit_signal_spec.rb +1 -1
  72. data/spec/integration_test/06_node_exit_after_task_spec.rb +4 -4
  73. data/spec/integration_test/08_shutdown_unused_nodes_spec.rb +2 -2
  74. data/spec/integration_test/09_server_process_data_spec.rb +1 -1
  75. data/spec/integration_test/definition/server01.rb +4 -5
  76. data/spec/integration_test/definition/server02.rb +2 -4
  77. data/spec/node/node_spec.rb +34 -0
  78. data/spec/server/message_spec.rb +1 -1
  79. data/spec/server/queue_spec.rb +34 -7
  80. data/spec/server/server_spec.rb +21 -9
  81. data/spec/server/transfer_setting_spec.rb +59 -24
  82. data/spec/setting/base_spec.rb +11 -0
  83. data/spec/setting/data_container_spec.rb +8 -0
  84. data/spec/spec_helper.rb +1 -7
  85. data/spec/task/registrar_spec.rb +34 -0
  86. data/spec/task/task_generator_spec.rb +15 -15
  87. data/spec/task/task_spec.rb +132 -23
  88. data/spec/utility/misc_spec.rb +2 -2
  89. data/spec/utility/transfer/transfer_client_connect_spec.rb +90 -0
  90. data/spec/utility/transfer/transfer_file_list_spec.rb +27 -0
  91. data/spec/{task/file_transfer_spec.rb → utility/transfer/transfer_spec.rb} +24 -24
  92. metadata +66 -45
  93. data/lib/drbqs/manage/execute_node.rb +0 -50
  94. data/lib/drbqs/server/prof.rb +0 -48
  95. data/lib/drbqs/task/command_task.rb +0 -43
  96. data/lib/drbqs/utility/transfer/file_transfer.rb +0 -73
@@ -1,85 +1,96 @@
1
1
  module DRbQS
2
-
3
- class ServerDefinition
4
- HELP_MESSAGE =<<HELP
2
+ class Execution
3
+ class ServerDefinition
4
+ HELP_MESSAGE =<<HELP
5
5
  * Server specific options
6
6
  These options are separated by '--' from command options.
7
7
 
8
8
  HELP
9
9
 
10
- def initialize
11
- clear_definition
12
- end
10
+ def initialize
11
+ clear_definition
12
+ end
13
13
 
14
- def define_server(default_opts = {}, &block)
15
- @default_server_opts = default_opts
16
- if @server_create
17
- raise ArgumentError, "The server has already defined."
14
+ def define_server(default_opts = {}, &block)
15
+ @default_server_opts = default_opts
16
+ if @server_create
17
+ raise ArgumentError, "The server has already defined."
18
+ end
19
+ @server_create = block
18
20
  end
19
- @server_create = block
20
- end
21
21
 
22
- def option_parser(&block)
23
- if @option_parse
24
- raise ArgumentError, "The options parser has already defined."
22
+ def option_parser(mes = nil, &block)
23
+ if @option_parse
24
+ raise ArgumentError, "The options parser has already defined."
25
+ end
26
+ @option_message = mes
27
+ @option_parse = block
25
28
  end
26
- @option_parse = block
27
- end
28
29
 
29
- def parse_option(opt_argv)
30
- if @option_parse
31
- OptionParser.new(HELP_MESSAGE) do |opt|
32
- @option_parse.call(opt, @opts)
33
- opt.parse!(opt_argv)
30
+ def create_parser(&block)
31
+ mes = HELP_MESSAGE
32
+ mes += @option_message.gsub(/(^\n+)|(\n+$)/, '') + "\n\n" if @option_message
33
+ OptionParser.new(mes) do |opt|
34
+ yield(opt)
34
35
  end
35
36
  end
36
- @argv = opt_argv
37
- end
37
+ private :create_parser
38
38
 
39
- def option_help_message
40
- if @option_parse
41
- OptionParser.new(HELP_MESSAGE) do |opt|
42
- @option_parse.call(opt, @opts)
43
- return opt.to_s
39
+ def parse_option(opt_argv)
40
+ if @option_parse
41
+ create_parser do |opt|
42
+ @option_parse.call(opt, @opts)
43
+ opt.parse!(opt_argv)
44
+ end
44
45
  end
45
- else
46
- nil
46
+ @argv = opt_argv
47
47
  end
48
- end
49
48
 
50
- def clear_definition
51
- @server_create = nil
52
- @option_parse = nil
53
- @opts = {}
54
- @argv = nil
55
- @default_server_opts = nil
56
- end
49
+ def option_help_message
50
+ if @option_parse
51
+ create_parser do |opt|
52
+ @option_parse.call(opt, @opts)
53
+ return opt.to_s
54
+ end
55
+ else
56
+ nil
57
+ end
58
+ end
57
59
 
58
- def create_server(options, klass = DRbQS::Server)
59
- server = klass.new(@default_server_opts.merge(options))
60
- @server_create.call(server, @argv, @opts)
61
- server.set_signal_trap
62
- server
63
- end
64
- private :create_server
60
+ def clear_definition
61
+ @server_create = nil
62
+ @option_parse = nil
63
+ @opts = {}
64
+ @argv = nil
65
+ @default_server_opts = nil
66
+ end
65
67
 
66
- def start_server(options)
67
- unless @server_create
68
- raise "Can not get server definition."
68
+ def create_server(options, klass = DRbQS::Server)
69
+ server = klass.new(@default_server_opts.merge(options))
70
+ @server_create.call(server, @argv, @opts)
71
+ server.set_signal_trap
72
+ server
69
73
  end
70
- server = create_server(options)
71
- server.start
72
- server.wait
73
- end
74
+ private :create_server
74
75
 
75
- def create_test_server(options)
76
- require 'drbqs/server/test/server'
77
- options[:finish_exit] = true
78
- create_server(options, DRbQS::Test::Server)
76
+ def start_server(options)
77
+ unless @server_create
78
+ raise "Can not get server definition."
79
+ end
80
+ server = create_server(options)
81
+ server.start
82
+ server.wait
83
+ end
84
+
85
+ def create_test_server(options)
86
+ require 'drbqs/server/test/server'
87
+ options.delete(:not_exit)
88
+ create_server(options, DRbQS::Test::Server)
89
+ end
79
90
  end
80
91
  end
81
92
 
82
- @@server_def = DRbQS::ServerDefinition.new
93
+ @@server_def = DRbQS::Execution::ServerDefinition.new
83
94
 
84
95
  class << self
85
96
  [:define_server, :option_parser, :parse_option, :option_help_message, :clear_definition,
@@ -0,0 +1,2 @@
1
+ require 'drbqs/task/task'
2
+ require 'drbqs/ext/task/command_task.rb'
@@ -0,0 +1,43 @@
1
+ module DRbQS
2
+ # Class to define tasks such that we execute a command.
3
+ class CommandTask < DRbQS::Task
4
+
5
+ # Execute a command and transfer files if needed.
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}"
14
+ end
15
+ @transfer = opts[:transfer]
16
+ @compress = opts[:compress]
17
+ end
18
+
19
+ def exec
20
+ case @cmd
21
+ when Array
22
+ @cmd.each { |c| system(c) }
23
+ when String
24
+ system(@cmd)
25
+ end
26
+ exit_status = $?.exitstatus
27
+ if @transfer
28
+ if @transfer.respond_to?(:each)
29
+ @transfer.each { |path| DRbQS::Transfer.enqueue(path, :compress => @compress) }
30
+ else
31
+ DRbQS::Transfer.enqueue(@transfer, :compress => @compress)
32
+ end
33
+ end
34
+ exit_status
35
+ end
36
+ end
37
+
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)
41
+ end
42
+ end
43
+ end
@@ -4,12 +4,13 @@ require 'drbqs/manage/send_signal'
4
4
 
5
5
  module DRbQS
6
6
  class Manage
7
- extend Forwardable
7
+ class NoServerRespond < StandardError
8
+ end
8
9
 
9
10
  class NotSetURI < StandardError
10
11
  end
11
- class NoServerRespond < StandardError
12
- end
12
+
13
+ extend Forwardable
13
14
 
14
15
  WAIT_SERVER_TIME = 0.2
15
16
  WAIT_MAX_NUMBER = 150
@@ -43,7 +44,7 @@ module DRbQS
43
44
  def signal_sender
44
45
  unless @signal_sender
45
46
  unless @opts[:uri]
46
- raise DRbQS::Manage::NotSetURI, "The uri has not set yet."
47
+ raise DRbQS::Manage::NotSetURI, "The uri of server to connect has not set."
47
48
  end
48
49
  obj = DRbObject.new_with_uri(@opts[:uri])
49
50
  @signal_sender = DRbQS::Manage::SendSignal.new(obj[:message])
@@ -2,7 +2,6 @@ require 'net/ssh'
2
2
  require 'net/ssh/shell'
3
3
 
4
4
  module DRbQS
5
-
6
5
  class Manage
7
6
  # Requirements:
8
7
  # bash
@@ -53,11 +52,6 @@ module DRbQS
53
52
  end
54
53
  end
55
54
 
56
- class InvalidDestination < StandardError
57
- end
58
- class GetInvalidExitStatus < StandardError
59
- end
60
-
61
55
  attr_reader :user, :host, :port, :keys
62
56
 
63
57
  # :shell shell to use
@@ -70,7 +64,7 @@ module DRbQS
70
64
  def initialize(dest, opts = {})
71
65
  @user, @host, @port = split_destination(dest)
72
66
  if !(@host && @user)
73
- raise InvalidDestination, "Invalid destination of ssh server."
67
+ raise ArgumentError, "Invalid ssh server: host=#{@host.inspect}, user=#{@user.inspect}."
74
68
  end
75
69
  @keys = opts.delete(:keys)
76
70
  @shell = opts[:shell] || 'bash'
@@ -137,7 +131,7 @@ module DRbQS
137
131
  ary = shell_exec(sh, cmd)
138
132
  n = ary[0].exit_status
139
133
  if n != 0
140
- raise GetInvalidExitStatus, "Can not execute properly on #{@host}.\nExit status: #{n}\ncommand: #{cmd}"
134
+ raise RuntimeError, "Can not execute properly on #{@host}.\nExit status: #{n}\ncommand: #{cmd}"
141
135
  end
142
136
  ary
143
137
  end
@@ -4,7 +4,7 @@ module DRbQS
4
4
  class Connection
5
5
  attr_reader :id, :node_number
6
6
 
7
- def initialize(message, logger = DRbQS::LoggerDummy.new)
7
+ def initialize(message, logger = DRbQS::Misc::LoggerDummy.new)
8
8
  @message = message
9
9
  @logger = logger
10
10
  @node_number = nil
@@ -1,6 +1,6 @@
1
1
  require 'drbqs/task/task'
2
- require 'drbqs/utility/transfer/transfer_client'
3
2
  require 'drbqs/utility/temporary'
3
+ require 'drbqs/utility/transfer/transfer_client'
4
4
  require 'drbqs/node/connection'
5
5
  require 'drbqs/node/task_client'
6
6
  require 'drbqs/node/state'
@@ -30,19 +30,13 @@ module DRbQS
30
30
  end
31
31
 
32
32
  def transfer_file
33
- if files = DRbQS::FileTransfer.dequeue_all
34
- if @transfer
35
- begin
36
- @transfer.transfer(files, server_on_same_host?)
37
- rescue => err
38
- @logger.error("Fail to transfer files.") do
39
- "Can not send file: #{files.join(", ")}\n#{err.to_s}\n#{err.backtrace.join("\n")}"
40
- end
41
- raise
42
- end
43
- else
44
- raise "Server does not set transfer settings. Can not send file: #{files.join(", ")}"
33
+ begin
34
+ DRbQS::Transfer::Client.transfer_to_server
35
+ rescue Exception => err
36
+ @logger.error("Fail to transfer files.") do
37
+ "#{err.to_s} (#{err.class})\n#{err.backtrace.join("\n")}"
45
38
  end
39
+ raise
46
40
  end
47
41
  end
48
42
  private :transfer_file
@@ -65,7 +59,7 @@ module DRbQS
65
59
  @server_key = obj[:key]
66
60
  @connection = Node::Connection.new(obj[:message], @logger)
67
61
  @task_client = Node::TaskClient.new(@connection.node_number, obj[:queue], obj[:result], @logger)
68
- @transfer = obj[:transfer]
62
+ DRbQS::Transfer::Client.set(obj[:transfer].get_client(server_on_same_host?)) if obj[:transfer]
69
63
  if ary = @connection.get_initialization
70
64
  execute_task(*ary)
71
65
  end
@@ -3,7 +3,7 @@ module DRbQS
3
3
  class TaskClient
4
4
  attr_reader :node_number, :calculating_task
5
5
 
6
- def initialize(node_number, queue, result, logger = DRbQS::LoggerDummy.new)
6
+ def initialize(node_number, queue, result, logger = DRbQS::Misc::LoggerDummy.new)
7
7
  @node_number = node_number
8
8
  @queue = queue
9
9
  @result = result
@@ -51,7 +51,11 @@ module DRbQS
51
51
  s << "Task #{task_id}\n"
52
52
  events.each do |ev|
53
53
  case ev[1]
54
- when :add, :requeue, :hook
54
+ when :add
55
+ s << " #{time_to_history_string(ev[0])}\t#{ev[1]}"
56
+ s << "\t" << ev[2].to_s if ev[2]
57
+ s << "\n"
58
+ when :requeue, :hook
55
59
  s << " #{time_to_history_string(ev[0])}\t#{ev[1]}\n"
56
60
  when :calculate, :result
57
61
  s << " #{time_to_history_string(ev[0])}\t#{ev[1]} (node #{ev[2]})\n"
@@ -5,7 +5,7 @@ module DRbQS
5
5
  class Message
6
6
  include DRbQS::Misc
7
7
 
8
- def initialize(message, logger = DRbQS::LoggerDummy.new)
8
+ def initialize(message, logger = DRbQS::Misc::LoggerDummy.new)
9
9
  @message = message
10
10
  @node_list = DRbQS::Server::NodeList.new
11
11
  @logger = logger
@@ -113,43 +113,16 @@ module DRbQS
113
113
  send_signal(node_id, :exit_after_task)
114
114
  end
115
115
 
116
- # +data+ is a hash including server information.
117
- # The keys are :calculating_task_number, :finished_task_number, :stocked_task_number,
118
- # :calculating_nodes, and :generator_number.
119
- def send_status(data)
120
- s = "Nodes:\n"
121
- if @node_list.history.size == 0
122
- s << " none\n"
123
- else
124
- @node_list.history.each do |node_id, events|
125
- if events.size == 0
126
- s << "Empty history of node #{node_id}\n"
127
- else
128
- connect = events[0]
129
- s << sprintf("%4d %s\t", node_id, connect[2])
130
- if events.size > 1
131
- s << "start:#{time_to_history_string(connect[0])}"
132
- events[1..-1].each do |t, key|
133
- s << ", #{key}: #{time_to_history_string(t)}"
134
- end
135
- s << "\n"
136
- elsif data[:calculating_nodes]
137
- task_ids = data[:calculating_nodes][node_id].to_a
138
- s << "task: #{task_ids.map { |num| num.to_s }.join(', ')} (#{time_to_history_string(connect[0])})\n"
139
- end
140
- end
141
- end
142
- end
143
- s << "Server:\n"
144
- s << " calculating tasks: #{data[:calculating_task_number]}\n"
145
- s << " finished tasks : #{data[:finished_task_number]}\n"
146
- s << " stocked tasks : #{data[:stocked_task_number]}\n"
147
- s << " task generator : #{data[:generator_number]}"
116
+ def each_node_history(&block)
117
+ @node_list.history.each(&block)
118
+ end
119
+
120
+ def send_status(server_status_string)
148
121
  begin
149
122
  @message.take([:status, nil], 0)
150
123
  rescue Rinda::RequestExpiredError
151
124
  end
152
- @message.write([:status, s])
125
+ @message.write([:status, server_status_string])
153
126
  end
154
127
 
155
128
  def send_history(history_string)
@@ -6,7 +6,7 @@ module DRbQS
6
6
  class Queue
7
7
  attr_reader :calculating, :history
8
8
 
9
- def initialize(queue, result, logger = DRbQS::LoggerDummy.new)
9
+ def initialize(queue, result, logger = DRbQS::Misc::LoggerDummy.new)
10
10
  @queue = queue
11
11
  @result = result
12
12
  @task_id = 0
@@ -28,7 +28,7 @@ module DRbQS
28
28
  @logger.info("New task: #{@task_id}")
29
29
  @cache[@task_id] = task
30
30
  queue_task(@task_id)
31
- @history.set(@task_id, :add)
31
+ @history.set(@task_id, :add, task.note)
32
32
  @task_id
33
33
  end
34
34
 
@@ -101,6 +101,18 @@ module DRbQS
101
101
  count
102
102
  end
103
103
 
104
+ # Return a hash of which keys are node ID number and
105
+ # values are an array of pairs of task ID number and its message.
106
+ def calculating_task_message
107
+ mes = {}
108
+ @calculating.each do |node_id, task_id_ary|
109
+ mes[node_id] = task_id_ary.map do |n|
110
+ [n, @history.events(n)[0][2]]
111
+ end
112
+ end
113
+ mes
114
+ end
115
+
104
116
  def calculating_task_number
105
117
  @calculating.inject(0) { |s, key_val| s + key_val[1].size }
106
118
  end
@@ -8,40 +8,28 @@ require 'drbqs/server/server_hook'
8
8
 
9
9
  module DRbQS
10
10
 
11
- # When we set both empty_queue_hook and task_generator,
12
- # empty_queue_hook is prior to task_generator.
13
11
  class Server
12
+ include DRbQS::Misc
13
+
14
14
  WAIT_TIME_NODE_EXIT = 3
15
15
  WAIT_TIME_NODE_FINALIZE = 10
16
16
  WAIT_TIME_NEW_RESULT = 1
17
17
 
18
18
  attr_reader :queue, :uri
19
19
 
20
- # :port
21
- # Set the port of server.
22
- # :unix
23
- # Set the path of unix domain socket.
24
- # If :port is specified, :port is preceded.
25
- # :acl
26
- # Set the ACL instance.
27
- # :log_file
28
- # Set the path of log files.
29
- # :log_level
30
- # Set the level of logging.
31
- # :check_alive
32
- # Set the time interval of checking alive nodes.
33
- # :finish_exit
34
- # Exit programs in finish_hook.
35
- # :shutdown_unused_nodes
36
- # Shutdown unused nodes.
37
- # :signal_trap
38
- # Set trapping signal.
39
- # :sftp_user
40
- # Set user of sftp.
41
- # :sftp_host
42
- # Set host of sftp.
43
- # :file_directory
44
- # Set the setting of file directory.
20
+ # @param [Hash] opts The options of server
21
+ # @option opts [Hash] :port Set the port of server.
22
+ # @option opts [Hash] :unix Set the path of unix domain socket. If :port is specified then :port is preceded.
23
+ # @option opts [Hash] :acl Set the ACL instance.
24
+ # @option opts [Hash] :log_file Set the path of log files.
25
+ # @option opts [Hash] :log_level Set the level of logging.
26
+ # @option opts [Hash] :check_alive Set the time interval of checking alive nodes.
27
+ # @option opts [Hash] :not_exit Not exit programs when all tasks are finished.
28
+ # @option opts [Hash] :shutdown_unused_nodes Shutdown unused nodes.
29
+ # @option opts [Hash] :signal_trap Set trapping signal. Default is true.
30
+ # @option opts [Hash] :sftp_user Set user of sftp.
31
+ # @option opts [Hash] :sftp_host Set host of sftp.
32
+ # @option opts [Hash] :file_directory Set the directory for nodes to send files.
45
33
  def initialize(opts = {})
46
34
  @uri = DRbQS::Misc.create_uri(opts)
47
35
  @acl = acl_init(opts[:acl])
@@ -58,8 +46,8 @@ module DRbQS
58
46
  @queue= DRbQS::Server::Queue.new(@ts[:queue], @ts[:result], @logger)
59
47
  @check_alive = DRbQS::Server::CheckAlive.new(opts[:check_alive])
60
48
  @task_generator = []
61
- hook_init(opts[:finish_exit], opts[:shutdown_unused_nodes])
62
- set_signal_trap if opts[:signal_trap]
49
+ hook_init(!opts[:not_exit], opts[:shutdown_unused_nodes])
50
+ set_signal_trap if !opts.has_key?(:signal_trap) || opts[:signal_trap]
63
51
  @finalization_task = nil
64
52
  @data_storage = []
65
53
  @transfer_setting = DRbQS::Server::TransferSetting.new(opts[:sftp_host], opts[:sftp_user], opts[:file_directory])
@@ -67,7 +55,7 @@ module DRbQS
67
55
  end
68
56
 
69
57
  def transfer_directory
70
- @ts[:transfer] && @ts[:transfer].directory
58
+ @transfer_setting.prepared_directory
71
59
  end
72
60
 
73
61
  def acl_init(acl_arg)
@@ -94,6 +82,7 @@ module DRbQS
94
82
  end
95
83
  private :server_data
96
84
 
85
+ # Initialize and start druby service.
97
86
  def start
98
87
  set_file_transfer(nil)
99
88
  DRb.install_acl(@acl) if @acl
@@ -112,10 +101,20 @@ module DRbQS
112
101
  end
113
102
  private :check_connection
114
103
 
104
+ # @param [DRbQS::Task::Generator] task_generator
115
105
  def add_task_generator(task_generator)
116
106
  @task_generator << task_generator
117
107
  end
118
108
 
109
+ # Create new task generator and add it.
110
+ # The arguments are same as {DRbQS::Task::Generator#set}.
111
+ def task_generator(opts = {}, &block)
112
+ gen = DRbQS::Task::Generator.new
113
+ gen.set(opts, &block)
114
+ add_task_generator(gen)
115
+ nil
116
+ end
117
+
119
118
  # If current task generator waits for finish of created tasks,
120
119
  # this method returns true.
121
120
  def generator_waiting?
@@ -145,17 +144,23 @@ module DRbQS
145
144
  end
146
145
  private :all_tasks_assigned?
147
146
 
147
+ # @param [DRbQS::task] task
148
148
  def set_initialization_task(task)
149
149
  @message.set_initialization(task)
150
150
  end
151
151
 
152
+ # @param [DRbQS::task] task
152
153
  def set_finalization_task(task)
153
154
  @finalization_task = task
154
155
  @message.set_finalization(@finalization_task)
155
156
  end
156
157
 
157
- # +key+ is :empty_queue, :process_data, or :finish_exit.
158
- # &block takes self as an argument.
158
+ # Set a hook of server.
159
+ # @note When we set both :empty_queue and task generators,
160
+ # hook of :empty_queue is prior to task generators.
161
+ # @param [:empty_queue,:process_data,:finish] key Set the type of hook.
162
+ # @param [String] name Name of the hook. If the value is nil then the name is automatically created.
163
+ # @param [Proc] &block block is obligatory and takes server itself as an argument.
159
164
  def add_hook(key, name = nil, &block)
160
165
  if key == :process_data
161
166
  if @hook.number_of_hook(:process_data) != 0
@@ -165,6 +170,8 @@ module DRbQS
165
170
  @hook.add(key, name, &block)
166
171
  end
167
172
 
173
+ # @param [:empty_queue,:process_data,:finish] key Set the type of hook.
174
+ # @param [String] name Name of the hook. If the value is nil then all hooks of the key is deleted.
168
175
  def delete_hook(key, name = nil)
169
176
  @hook.delete(key, name)
170
177
  end
@@ -249,19 +256,25 @@ module DRbQS
249
256
 
250
257
  def set_signal_trap
251
258
  Signal.trap(:TERM) do
259
+ @logger.error("Get TERM signal.")
252
260
  self.exit
253
261
  end
254
262
  end
255
263
 
264
+ # @param [String] directory Set the directory to save files from nodes.
265
+ # @param [Hash] opts The options for SFTP.
266
+ # @option opts [Symbol] :host Hostname for SFTP.
267
+ # @option opts [Symbol] :user User name for SFTP.
256
268
  def set_file_transfer(directory, opts = {})
257
- if transfer = @transfer_setting.create(directory, opts)
258
- @ts[:transfer] = transfer
259
- @logger.info("File transfer") { transfer.information }
269
+ if @transfer_setting.setup_server(directory, opts)
270
+ @ts[:transfer] = @transfer_setting
271
+ @logger.info("File transfer") { @transfer_setting.information }
260
272
  end
261
273
  end
262
274
 
263
275
  # Set *args to data storage, which must be string objects.
264
276
  # The data is processed by hook of :process_data.
277
+ # @param [Array] args An array of data strings.
265
278
  def set_data(*args)
266
279
  args.each do |s|
267
280
  if String === s
@@ -282,14 +295,44 @@ module DRbQS
282
295
  private :process_data
283
296
 
284
297
  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)
298
+ messages = @queue.calculating_task_message
299
+ s = ''
300
+ @message.each_node_history do|node_id, events|
301
+ if events.size == 0
302
+ s << "Empty history of node #{node_id}\n"
303
+ else
304
+ connect = events[0]
305
+ s << sprintf("%4d %s\t", node_id, connect[2])
306
+ if events.size > 1
307
+ s << "start:#{time_to_history_string2(connect[0])}"
308
+ events[1..-1].each do |t, key|
309
+ s << ", #{key}: #{time_to_history_string2(t)}"
310
+ end
311
+ s << "\n"
312
+ else
313
+ task_ids = @queue.calculating[node_id].to_a
314
+ s << "task: "
315
+ if messages[node_id]
316
+ s << messages[node_id].map do |task_id, mes|
317
+ calc_task = task_id.to_s
318
+ calc_task << ": " << mes.to_s if mes
319
+ calc_task
320
+ end.join(', ')
321
+ else
322
+ s << "none"
323
+ end
324
+ s << " (#{time_to_history_string2(connect[0])})\n"
325
+ end
326
+ end
327
+ end
328
+ s << " none\n" if s.size == 0
329
+ s = "Nodes:\n" << s
330
+ s << "Server:\n"
331
+ s << " calculating tasks: #{@queue.calculating_task_number}\n"
332
+ s << " finished tasks : #{@queue.finished_task_number}\n"
333
+ s << " stocked tasks : #{@queue.stocked_task_number}\n"
334
+ s << " task generator : #{@task_generator.size}"
335
+ @message.send_status(s)
293
336
  end
294
337
  private :send_status_for_request
295
338