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.
- data/.document +3 -0
- data/README.md +137 -128
- data/VERSION +1 -1
- data/docs/FormatExecute.md +119 -0
- data/docs/GettingStarted.md +242 -0
- data/drbqs.gemspec +36 -13
- data/example/command/server_def.rb +4 -5
- data/example/execute/execute.rb +41 -0
- data/example/execute/server.rb +14 -0
- data/example/execute/task.rb +0 -0
- data/example/mandelbrot/README.md +15 -0
- data/example/mandelbrot/execute.rb +10 -0
- data/example/mandelbrot/mandelbrot.rb +56 -0
- data/example/mandelbrot/server.rb +49 -0
- data/example/server/server.rb +3 -6
- data/example/simple/README.md +18 -0
- data/example/simple/execute.rb +11 -0
- data/example/simple/server.rb +8 -0
- data/example/simple/task.rb +11 -0
- data/example/sum/server_def.rb +1 -1
- data/example/sum2/execute_def.rb +21 -8
- data/example/sum2/server_def.rb +8 -7
- data/example/transfer/file.rb +42 -8
- data/example/transfer/server_def.rb +43 -9
- data/lib/drbqs.rb +1 -1
- data/lib/drbqs/command_line/command_execute.rb +3 -3
- data/lib/drbqs/command_line/command_line.rb +1 -1
- data/lib/drbqs/execute/execute_node.rb +50 -0
- data/lib/drbqs/execute/process_define.rb +102 -54
- data/lib/drbqs/execute/register.rb +241 -87
- data/lib/drbqs/execute/server_define.rb +69 -58
- data/lib/drbqs/ext/task.rb +2 -0
- data/lib/drbqs/ext/task/command_task.rb +43 -0
- data/lib/drbqs/manage/manage.rb +5 -4
- data/lib/drbqs/manage/ssh_shell.rb +2 -8
- data/lib/drbqs/node/connection.rb +1 -1
- data/lib/drbqs/node/node.rb +8 -14
- data/lib/drbqs/node/task_client.rb +1 -1
- data/lib/drbqs/server/history.rb +5 -1
- data/lib/drbqs/server/message.rb +7 -34
- data/lib/drbqs/server/queue.rb +14 -2
- data/lib/drbqs/server/server.rb +86 -43
- data/lib/drbqs/server/server_hook.rb +3 -0
- data/lib/drbqs/server/test/node.rb +1 -1
- data/lib/drbqs/server/test/prof.rb +50 -0
- data/lib/drbqs/server/test/server.rb +2 -2
- data/lib/drbqs/server/transfer_setting.rb +23 -11
- data/lib/drbqs/setting/base.rb +15 -0
- data/lib/drbqs/setting/data_container.rb +1 -1
- data/lib/drbqs/setting/execute.rb +3 -3
- data/lib/drbqs/setting/node.rb +1 -1
- data/lib/drbqs/setting/server.rb +2 -2
- data/lib/drbqs/task/registrar.rb +39 -0
- data/lib/drbqs/task/task.rb +139 -59
- data/lib/drbqs/task/task_generator.rb +93 -116
- data/lib/drbqs/utility/misc.rb +15 -10
- data/lib/drbqs/utility/temporary.rb +7 -2
- data/lib/drbqs/utility/transfer/transfer.rb +81 -0
- data/lib/drbqs/utility/transfer/transfer_client.rb +68 -69
- data/lib/drbqs/utility/transfer/transfer_client_connect.rb +83 -0
- data/lib/drbqs/utility/transfer/transfer_file_list.rb +40 -0
- data/spec/execute/def/execute1.rb +4 -4
- data/spec/execute/def/execute2.rb +24 -0
- data/spec/execute/process_define_spec.rb +43 -6
- data/spec/execute/register_spec.rb +403 -9
- data/spec/execute/server_define_spec.rb +1 -1
- data/spec/ext/task/command_task_spec.rb +16 -0
- data/spec/integration_test/01_basic_usage_spec.rb +1 -1
- data/spec/integration_test/02_use_generator_spec.rb +2 -2
- data/spec/integration_test/04_use_unix_domain_spec.rb +1 -1
- data/spec/integration_test/05_server_exit_signal_spec.rb +1 -1
- data/spec/integration_test/06_node_exit_after_task_spec.rb +4 -4
- data/spec/integration_test/08_shutdown_unused_nodes_spec.rb +2 -2
- data/spec/integration_test/09_server_process_data_spec.rb +1 -1
- data/spec/integration_test/definition/server01.rb +4 -5
- data/spec/integration_test/definition/server02.rb +2 -4
- data/spec/node/node_spec.rb +34 -0
- data/spec/server/message_spec.rb +1 -1
- data/spec/server/queue_spec.rb +34 -7
- data/spec/server/server_spec.rb +21 -9
- data/spec/server/transfer_setting_spec.rb +59 -24
- data/spec/setting/base_spec.rb +11 -0
- data/spec/setting/data_container_spec.rb +8 -0
- data/spec/spec_helper.rb +1 -7
- data/spec/task/registrar_spec.rb +34 -0
- data/spec/task/task_generator_spec.rb +15 -15
- data/spec/task/task_spec.rb +132 -23
- data/spec/utility/misc_spec.rb +2 -2
- data/spec/utility/transfer/transfer_client_connect_spec.rb +90 -0
- data/spec/utility/transfer/transfer_file_list_spec.rb +27 -0
- data/spec/{task/file_transfer_spec.rb → utility/transfer/transfer_spec.rb} +24 -24
- metadata +66 -45
- data/lib/drbqs/manage/execute_node.rb +0 -50
- data/lib/drbqs/server/prof.rb +0 -48
- data/lib/drbqs/task/command_task.rb +0 -43
- data/lib/drbqs/utility/transfer/file_transfer.rb +0 -73
@@ -1,85 +1,96 @@
|
|
1
1
|
module DRbQS
|
2
|
-
|
3
|
-
|
4
|
-
|
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
|
-
|
11
|
-
|
12
|
-
|
10
|
+
def initialize
|
11
|
+
clear_definition
|
12
|
+
end
|
13
13
|
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
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
|
-
|
23
|
-
|
24
|
-
|
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
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
opt
|
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
|
-
|
37
|
-
end
|
37
|
+
private :create_parser
|
38
38
|
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
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
|
-
|
46
|
-
nil
|
46
|
+
@argv = opt_argv
|
47
47
|
end
|
48
|
-
end
|
49
48
|
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
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
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
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
|
-
|
67
|
-
|
68
|
-
|
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
|
-
|
71
|
-
server.start
|
72
|
-
server.wait
|
73
|
-
end
|
74
|
+
private :create_server
|
74
75
|
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
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,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
|
data/lib/drbqs/manage/manage.rb
CHANGED
@@ -4,12 +4,13 @@ require 'drbqs/manage/send_signal'
|
|
4
4
|
|
5
5
|
module DRbQS
|
6
6
|
class Manage
|
7
|
-
|
7
|
+
class NoServerRespond < StandardError
|
8
|
+
end
|
8
9
|
|
9
10
|
class NotSetURI < StandardError
|
10
11
|
end
|
11
|
-
|
12
|
-
|
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
|
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
|
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
|
134
|
+
raise RuntimeError, "Can not execute properly on #{@host}.\nExit status: #{n}\ncommand: #{cmd}"
|
141
135
|
end
|
142
136
|
ary
|
143
137
|
end
|
data/lib/drbqs/node/node.rb
CHANGED
@@ -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
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
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
|
-
|
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
|
data/lib/drbqs/server/history.rb
CHANGED
@@ -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
|
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"
|
data/lib/drbqs/server/message.rb
CHANGED
@@ -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
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
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,
|
125
|
+
@message.write([:status, server_status_string])
|
153
126
|
end
|
154
127
|
|
155
128
|
def send_history(history_string)
|
data/lib/drbqs/server/queue.rb
CHANGED
@@ -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
|
data/lib/drbqs/server/server.rb
CHANGED
@@ -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
|
-
#
|
21
|
-
#
|
22
|
-
# :unix
|
23
|
-
#
|
24
|
-
#
|
25
|
-
# :
|
26
|
-
#
|
27
|
-
# :
|
28
|
-
#
|
29
|
-
# :
|
30
|
-
#
|
31
|
-
# :
|
32
|
-
#
|
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[:
|
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
|
-
@
|
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
|
-
#
|
158
|
-
#
|
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
|
258
|
-
@ts[:transfer] =
|
259
|
-
@logger.info("File transfer") {
|
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
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
|
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
|
|