drbqs 0.0.15 → 0.0.16

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