drbqs 0.0.13 → 0.0.14
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/Gemfile +10 -7
- data/README.md +52 -11
- data/Rakefile +32 -10
- data/VERSION +1 -1
- data/bin/drbqs-manage +3 -93
- data/bin/drbqs-node +3 -89
- data/bin/drbqs-server +3 -117
- data/bin/drbqs-ssh +6 -0
- data/drbqs.gemspec +118 -97
- data/example/README.md +2 -2
- data/lib/drbqs/config/config.rb +88 -0
- data/lib/drbqs/config/process_list.rb +194 -0
- data/lib/drbqs/config/ssh_host.rb +41 -0
- data/lib/drbqs/{execute_node.rb → manage/execute_node.rb} +6 -4
- data/lib/drbqs/manage/manage.rb +100 -0
- data/lib/drbqs/manage/send_signal.rb +45 -0
- data/lib/drbqs/manage/ssh_execute.rb +23 -0
- data/lib/drbqs/manage/ssh_shell.rb +143 -0
- data/lib/drbqs/node/connection.rb +69 -0
- data/lib/drbqs/{client.rb → node/node.rb} +48 -18
- data/lib/drbqs/node/task_client.rb +94 -0
- data/lib/drbqs/server/acl_file.rb +15 -0
- data/lib/drbqs/server/check_alive.rb +23 -0
- data/lib/drbqs/server/history.rb +49 -0
- data/lib/drbqs/server/message.rb +142 -0
- data/lib/drbqs/server/node_list.rb +59 -0
- data/lib/drbqs/server/queue.rb +128 -0
- data/lib/drbqs/{server.rb → server/server.rb} +66 -74
- data/lib/drbqs/server/server_hook.rb +72 -0
- data/lib/drbqs/server/transfer_setting.rb +30 -0
- data/lib/drbqs/task/command_task.rb +43 -0
- data/lib/drbqs/{task.rb → task/task.rb} +18 -39
- data/lib/drbqs/{task_generator.rb → task/task_generator.rb} +2 -0
- data/lib/drbqs/utility/argument.rb +27 -0
- data/lib/drbqs/utility/command_line/command_base.rb +27 -0
- data/lib/drbqs/utility/command_line/command_manage.rb +121 -0
- data/lib/drbqs/utility/command_line/command_node.rb +103 -0
- data/lib/drbqs/utility/command_line/command_server.rb +165 -0
- data/lib/drbqs/utility/command_line/command_ssh.rb +126 -0
- data/lib/drbqs/utility/command_line.rb +15 -0
- data/lib/drbqs/utility/misc.rb +72 -0
- data/lib/drbqs/{server_define.rb → utility/server_define.rb} +23 -8
- data/lib/drbqs/utility/temporary.rb +49 -0
- data/lib/drbqs/{ssh/transfer.rb → utility/transfer/file_transfer.rb} +18 -58
- data/lib/drbqs/utility/transfer/transfer_client.rb +90 -0
- data/lib/drbqs.rb +10 -22
- data/spec/config/config_spec.rb +84 -0
- data/spec/config/process_list_spec.rb +149 -0
- data/spec/config/ssh_host_spec.rb +81 -0
- data/spec/integration_test/01_basic_usage_spec.rb +54 -0
- data/spec/integration_test/02_use_generator_spec.rb +53 -0
- data/spec/integration_test/03_use_temporary_file_spec.rb +26 -0
- data/spec/integration_test/04_use_unix_domain_spec.rb +34 -0
- data/spec/integration_test/05_server_exit_signal_spec.rb +23 -0
- data/spec/integration_test/06_node_exit_after_task_spec.rb +42 -0
- data/spec/integration_test/07_command_server_with_node_spec.rb +44 -0
- data/spec/integration_test/definition/server01.rb +20 -0
- data/spec/integration_test/definition/server02.rb +16 -0
- data/spec/integration_test/definition/task_obj_definition.rb +49 -0
- data/spec/manage/manage_spec.rb +33 -0
- data/spec/manage/send_signal_spec.rb +39 -0
- data/spec/{ssh_shell_spec.rb → manage/ssh_shell_spec.rb} +8 -8
- data/spec/node/connection_spec.rb +66 -0
- data/spec/node/task_client_spec.rb +212 -0
- data/spec/server/acl_file_spec.rb +9 -0
- data/spec/{server_check_alive_spec.rb → server/check_alive_spec.rb} +15 -11
- data/spec/{data → server/data}/acl.txt +0 -0
- data/spec/{history_spec.rb → server/history_spec.rb} +9 -5
- data/spec/server/message_spec.rb +195 -0
- data/spec/server/node_list_spec.rb +111 -0
- data/spec/server/queue_spec.rb +239 -0
- data/spec/{server_hook_spec.rb → server/server_hook_spec.rb} +23 -17
- data/spec/server/server_spec.rb +89 -0
- data/spec/server/transfer_setting_spec.rb +37 -0
- data/spec/spec_helper.rb +65 -0
- data/spec/task/file_transfer_spec.rb +107 -0
- data/spec/{task_generator_spec.rb → task/task_generator_spec.rb} +2 -2
- data/spec/{task_spec.rb → task/task_spec.rb} +3 -1
- data/spec/utility/argument_spec.rb +39 -0
- data/spec/utility/command_line/command_base_spec.rb +33 -0
- data/spec/utility/command_line/commands_spec.rb +15 -0
- data/spec/utility/misc_spec.rb +77 -0
- data/spec/utility/server_define_spec.rb +59 -0
- data/spec/utility/temporary_spec.rb +39 -0
- metadata +158 -93
- data/example/drbqs-manage-test.rb +0 -3
- data/example/drbqs-node-test.rb +0 -3
- data/example/drbqs-server-test.rb +0 -3
- data/lib/drbqs/acl_file.rb +0 -13
- data/lib/drbqs/config.rb +0 -98
- data/lib/drbqs/connection.rb +0 -67
- data/lib/drbqs/history.rb +0 -34
- data/lib/drbqs/manage.rb +0 -84
- data/lib/drbqs/message.rb +0 -119
- data/lib/drbqs/node_list.rb +0 -52
- data/lib/drbqs/queue.rb +0 -138
- data/lib/drbqs/server_hook.rb +0 -67
- data/lib/drbqs/ssh/host.rb +0 -26
- data/lib/drbqs/ssh/shell.rb +0 -139
- data/lib/drbqs/task_client.rb +0 -86
- data/lib/drbqs/utils.rb +0 -19
- data/spec/acl_file_spec.rb +0 -9
- data/spec/config_spec.rb +0 -14
- data/spec/connection_spec.rb +0 -49
- data/spec/manage_spec.rb +0 -57
- data/spec/message_spec.rb +0 -81
- data/spec/node_list_spec.rb +0 -68
- data/spec/queue_spec.rb +0 -59
- data/spec/server_define_spec.rb +0 -45
- data/spec/server_spec.rb +0 -56
- data/spec/task_client_spec.rb +0 -53
- data/spec/test/test1.rb +0 -13
- data/spec/test1_spec.rb +0 -80
- data/spec/test2_spec.rb +0 -69
- data/spec/transfer_spec.rb +0 -13
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
require 'drbqs/manage/ssh_execute'
|
|
2
|
+
require 'drbqs/manage/send_signal'
|
|
3
|
+
|
|
4
|
+
module DRbQS
|
|
5
|
+
class Manage
|
|
6
|
+
class NotSetURI < StandardError
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
WAIT_SERVER_TIME = 0.3
|
|
10
|
+
WAIT_MAX_NUMBER = 200
|
|
11
|
+
|
|
12
|
+
# +opts+ has keys :home and :uri.
|
|
13
|
+
def initialize(opts = {})
|
|
14
|
+
@opts = opts
|
|
15
|
+
@config = nil
|
|
16
|
+
@signal_sender = nil
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def set_uri(uri)
|
|
20
|
+
@opts[:uri] = uri
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def set_home_directory(dir)
|
|
24
|
+
@opts[:home] = dir
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def config
|
|
28
|
+
unless @config
|
|
29
|
+
if @opts[:home]
|
|
30
|
+
DRbQS::Config.set_home_directory(@opts[:home])
|
|
31
|
+
end
|
|
32
|
+
@config = DRbQS::Config.new
|
|
33
|
+
end
|
|
34
|
+
@config
|
|
35
|
+
end
|
|
36
|
+
private :config
|
|
37
|
+
|
|
38
|
+
def signal_sender
|
|
39
|
+
unless @signal_sender
|
|
40
|
+
unless @opts[:uri]
|
|
41
|
+
raise DRbQS::Manage::NotSetURI, "The uri has not set yet."
|
|
42
|
+
end
|
|
43
|
+
obj = DRbObject.new_with_uri(@opts[:uri])
|
|
44
|
+
@signal_sender = DRbQS::Manage::SendSignal.new(obj[:message])
|
|
45
|
+
end
|
|
46
|
+
@signal_sender
|
|
47
|
+
end
|
|
48
|
+
private :signal_sender
|
|
49
|
+
|
|
50
|
+
def create_config
|
|
51
|
+
config.save_sample
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def send_exit_signal
|
|
55
|
+
signal_sender.send_exit_signal
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def send_node_exit_after_task(node_id)
|
|
59
|
+
signal_sender.send_node_exit_after_task(node_id)
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def get_status
|
|
63
|
+
signal_sender.get_status
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def server_respond?
|
|
67
|
+
begin
|
|
68
|
+
get_status
|
|
69
|
+
true
|
|
70
|
+
rescue DRbQS::Manage::NotSetURI
|
|
71
|
+
raise
|
|
72
|
+
rescue
|
|
73
|
+
nil
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
def wait_server_process(pid)
|
|
78
|
+
i = 0
|
|
79
|
+
begin
|
|
80
|
+
sleep(WAIT_SERVER_TIME)
|
|
81
|
+
unless DRbQS::Misc.process_running_normally?(pid)
|
|
82
|
+
return nil
|
|
83
|
+
end
|
|
84
|
+
i += 1
|
|
85
|
+
if i > WAIT_MAX_NUMBER
|
|
86
|
+
raise "Can not wait server process."
|
|
87
|
+
end
|
|
88
|
+
end while !server_respond?
|
|
89
|
+
true
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
def list_process
|
|
93
|
+
{ :server => config.list.server.list, :node => config.list.node.list }
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
def clear_process
|
|
97
|
+
config.list.clear_process_not_exist
|
|
98
|
+
end
|
|
99
|
+
end
|
|
100
|
+
end
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
module DRbQS
|
|
2
|
+
class Manage
|
|
3
|
+
class SendSignal
|
|
4
|
+
MAX_WAIT_TIME = 10
|
|
5
|
+
|
|
6
|
+
def initialize(message)
|
|
7
|
+
@message = message
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def sender_id
|
|
11
|
+
"#{Socket.gethostname}/#{Process.pid}"
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def send_signal_to_server(signal, arg)
|
|
15
|
+
@message.write([:server, signal, arg])
|
|
16
|
+
end
|
|
17
|
+
private :send_signal_to_server
|
|
18
|
+
|
|
19
|
+
def send_exit_signal
|
|
20
|
+
send_signal_to_server(:exit_server, sender_id)
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def send_node_exit_after_task(node_id)
|
|
24
|
+
send_signal_to_server(:exit_after_task, node_id)
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def get_status
|
|
28
|
+
send_signal_to_server(:request_status, sender_id)
|
|
29
|
+
i = 0
|
|
30
|
+
loop do
|
|
31
|
+
begin
|
|
32
|
+
mes = @message.take([:status, String], 0)
|
|
33
|
+
return mes[1]
|
|
34
|
+
rescue Rinda::RequestExpiredError
|
|
35
|
+
i += 1
|
|
36
|
+
if i > MAX_WAIT_TIME
|
|
37
|
+
return nil
|
|
38
|
+
end
|
|
39
|
+
sleep(1)
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
require 'drbqs/manage/ssh_shell'
|
|
2
|
+
|
|
3
|
+
module DRbQS
|
|
4
|
+
class Manage
|
|
5
|
+
class SSHExecute
|
|
6
|
+
def initialize(dest, opts = {})
|
|
7
|
+
@ssh_host = DRbQS::Config.new.ssh_host
|
|
8
|
+
path, options = @ssh_host.get_options(dest)
|
|
9
|
+
# $stdout.puts "Use configuration: #{path}" if path
|
|
10
|
+
dest = options[:dest] || dest
|
|
11
|
+
@ssh = DRbQS::Manage::SSHShell.new(dest, options.merge(opts))
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def execute(command)
|
|
15
|
+
@ssh.start(command)
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def get_environment
|
|
19
|
+
@ssh.get_environment
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
require 'net/ssh'
|
|
2
|
+
require 'net/ssh/shell'
|
|
3
|
+
|
|
4
|
+
module DRbQS
|
|
5
|
+
|
|
6
|
+
class Manage
|
|
7
|
+
# Requirements:
|
|
8
|
+
# bash
|
|
9
|
+
# nohup
|
|
10
|
+
class SSHShell
|
|
11
|
+
class InvalidDestination < StandardError
|
|
12
|
+
end
|
|
13
|
+
class GetInvalidExitStatus < StandardError
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
attr_reader :user, :host, :directory, :port
|
|
17
|
+
|
|
18
|
+
DEFAULT_RVM_SCRIPT = '$HOME/.rvm/scripts/rvm'
|
|
19
|
+
DEFAULT_OUTPUT_FILE = 'drbqs_nohup.log'
|
|
20
|
+
|
|
21
|
+
# :shell shell to use
|
|
22
|
+
# :dir base directory of ssh server
|
|
23
|
+
# :rvm version of ruby on rvm
|
|
24
|
+
# :rvm_init path of script to initialize rvm
|
|
25
|
+
# :output file to output of stdout and stderr
|
|
26
|
+
def initialize(dest, opts = {})
|
|
27
|
+
@user, @host, @port = split_destination(dest)
|
|
28
|
+
if !(@host && @user)
|
|
29
|
+
raise InvalidDestination, "Invalid destination of ssh server."
|
|
30
|
+
end
|
|
31
|
+
@shell = opts[:shell] || 'bash'
|
|
32
|
+
@rvm = opts[:rvm]
|
|
33
|
+
@rvm_init = opts[:rvm_init]
|
|
34
|
+
if (@rvm || @rvm_init) && !(String === @rvm_init)
|
|
35
|
+
@rvm_init = DEFAULT_RVM_SCRIPT
|
|
36
|
+
end
|
|
37
|
+
@nohup_output = opts[:output] || DEFAULT_OUTPUT_FILE
|
|
38
|
+
@directory = opts[:dir]
|
|
39
|
+
@out = $stdout
|
|
40
|
+
@nice = opts[:nice]
|
|
41
|
+
@nohup = opts[:nohup]
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def split_destination(dest)
|
|
45
|
+
if (n = dest.index("@")) && n > 0
|
|
46
|
+
user = dest[0..(n - 1)]
|
|
47
|
+
host_dir = dest[(n + 1)..-1]
|
|
48
|
+
else
|
|
49
|
+
raise "Not include '@': #{dest}"
|
|
50
|
+
end
|
|
51
|
+
if n = host_dir.index(':')
|
|
52
|
+
host = host_dir[0..(n - 1)]
|
|
53
|
+
port = host_dir[(n + 1)..-1]
|
|
54
|
+
else
|
|
55
|
+
host = host_dir
|
|
56
|
+
port = nil
|
|
57
|
+
end
|
|
58
|
+
[user && user.size > 0 ? user : nil,
|
|
59
|
+
host && host.size > 0 ? host : nil,
|
|
60
|
+
port && port.size > 0 ? port.to_i : nil]
|
|
61
|
+
end
|
|
62
|
+
private :split_destination
|
|
63
|
+
|
|
64
|
+
def output_command(cmd, result)
|
|
65
|
+
@out.puts "#{@user}@#{@host}$ #{cmd}" if @out
|
|
66
|
+
@out.print result
|
|
67
|
+
end
|
|
68
|
+
private :output_command
|
|
69
|
+
|
|
70
|
+
def shell_exec_get_output(sh, cmd)
|
|
71
|
+
result = ''
|
|
72
|
+
pr_cmd = sh.execute!(cmd) do |sh_proc|
|
|
73
|
+
sh_proc.on_output do |pr, data|
|
|
74
|
+
result << data
|
|
75
|
+
end
|
|
76
|
+
sh_proc.on_error_output do |pr, data|
|
|
77
|
+
result << data
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
[pr_cmd, result]
|
|
81
|
+
end
|
|
82
|
+
private :shell_exec_get_output
|
|
83
|
+
|
|
84
|
+
def shell_exec(sh, cmd)
|
|
85
|
+
ary = shell_exec_get_output(sh, cmd)
|
|
86
|
+
output_command(cmd, ary[1])
|
|
87
|
+
ary
|
|
88
|
+
end
|
|
89
|
+
private :shell_exec
|
|
90
|
+
|
|
91
|
+
def shell_exec_check(sh, cmd)
|
|
92
|
+
ary = shell_exec(sh, cmd)
|
|
93
|
+
if ary[0].exit_status != 0
|
|
94
|
+
raise GetInvalidExitStatus, "Can not execute '#{cmd}' on #{@host} properly."
|
|
95
|
+
end
|
|
96
|
+
ary
|
|
97
|
+
end
|
|
98
|
+
private :shell_exec_check
|
|
99
|
+
|
|
100
|
+
def execute_command(&block)
|
|
101
|
+
Net::SSH.start(@host, @user, :port => @port) do |ssh|
|
|
102
|
+
ssh.shell(@shell) do |sh|
|
|
103
|
+
shell_exec_check(sh, "cd #{@directory}") if @directory
|
|
104
|
+
shell_exec_check(sh, "source #{@rvm_init}") if @rvm_init
|
|
105
|
+
shell_exec_check(sh, "rvm use #{@rvm}") if @rvm
|
|
106
|
+
yield(sh)
|
|
107
|
+
shell_exec(sh, "exit")
|
|
108
|
+
end
|
|
109
|
+
end
|
|
110
|
+
end
|
|
111
|
+
private :execute_command
|
|
112
|
+
|
|
113
|
+
def get_environment
|
|
114
|
+
execute_command do |sh|
|
|
115
|
+
['echo "directory: " `pwd`',
|
|
116
|
+
'echo "files:"',
|
|
117
|
+
'ls',
|
|
118
|
+
'if which rvm > /dev/null; then rvm info; else ruby -v; fi'].each do |cmd|
|
|
119
|
+
shell_exec(sh, cmd)
|
|
120
|
+
end
|
|
121
|
+
end
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
def start(*args)
|
|
125
|
+
cmd = args.join(' ')
|
|
126
|
+
if @nice
|
|
127
|
+
if Integer === @nice
|
|
128
|
+
cmd = "nice -n #{@nice.to_s} " + cmd
|
|
129
|
+
else
|
|
130
|
+
cmd = "nice " + cmd
|
|
131
|
+
end
|
|
132
|
+
end
|
|
133
|
+
execute_command do |sh|
|
|
134
|
+
if @nohup
|
|
135
|
+
pr, path = shell_exec_check(sh, "filename-create new -p middle -D parent -t time #{@nohup_output}")
|
|
136
|
+
cmd = "nohup #{cmd} > #{path.strip} 2>&1 &"
|
|
137
|
+
end
|
|
138
|
+
shell_exec(sh, cmd)
|
|
139
|
+
end
|
|
140
|
+
end
|
|
141
|
+
end
|
|
142
|
+
end
|
|
143
|
+
end
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
module DRbQS
|
|
2
|
+
class Node
|
|
3
|
+
# The class of connection to server.
|
|
4
|
+
class Connection
|
|
5
|
+
attr_reader :id, :node_number
|
|
6
|
+
|
|
7
|
+
def initialize(message, logger = DRbQS::LoggerDummy.new)
|
|
8
|
+
@message = message
|
|
9
|
+
@logger = logger
|
|
10
|
+
@node_number = nil
|
|
11
|
+
@id = create_id_string
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def create_id_string
|
|
15
|
+
t = Time.now
|
|
16
|
+
sprintf("#{Socket.gethostname}:%d", Process.pid)
|
|
17
|
+
end
|
|
18
|
+
private :create_id_string
|
|
19
|
+
|
|
20
|
+
def node_number
|
|
21
|
+
unless @node_number
|
|
22
|
+
@message.write([:server, :connect, @id])
|
|
23
|
+
@node_number = @message.take([@id, Fixnum])[1]
|
|
24
|
+
@logger.info("Get node id: #{@node_number}")
|
|
25
|
+
end
|
|
26
|
+
@node_number
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def get_special_task(label)
|
|
30
|
+
begin
|
|
31
|
+
ary = @message.read([label, nil, Symbol, nil], 0)
|
|
32
|
+
ary[1..-1]
|
|
33
|
+
rescue Rinda::RequestExpiredError
|
|
34
|
+
nil
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
private :get_special_task
|
|
38
|
+
|
|
39
|
+
def get_initialization
|
|
40
|
+
get_special_task(:initialize)
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def get_finalization
|
|
44
|
+
get_special_task(:finalize)
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def respond_signal
|
|
48
|
+
begin
|
|
49
|
+
node_id, sym = @message.take([@node_number, Symbol], 0)
|
|
50
|
+
@logger.info("Get signal: #{sym.inspect}")
|
|
51
|
+
case sym
|
|
52
|
+
when :alive_p
|
|
53
|
+
@message.write([:server, :alive, @node_number])
|
|
54
|
+
@logger.info("Send alive signal of node id #{@node_number}")
|
|
55
|
+
when :exit, :finalize, :exit_after_task
|
|
56
|
+
return sym
|
|
57
|
+
else
|
|
58
|
+
raise "Get invalid signal: #{sym.inspect}"
|
|
59
|
+
end
|
|
60
|
+
rescue Rinda::RequestExpiredError
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def send_node_error(error_message)
|
|
65
|
+
@message.write([:server, :node_error, [@node_number, error_message]])
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
end
|
|
@@ -1,9 +1,12 @@
|
|
|
1
|
-
require 'drbqs/
|
|
2
|
-
require 'drbqs/
|
|
1
|
+
require 'drbqs/task/task'
|
|
2
|
+
require 'drbqs/utility/transfer/transfer_client'
|
|
3
|
+
require 'drbqs/node/connection'
|
|
4
|
+
require 'drbqs/node/task_client'
|
|
5
|
+
require 'drbqs/utility/temporary'
|
|
3
6
|
|
|
4
7
|
module DRbQS
|
|
5
8
|
|
|
6
|
-
class
|
|
9
|
+
class Node
|
|
7
10
|
|
|
8
11
|
WAIT_NEW_TASK = 1
|
|
9
12
|
PRIORITY_RESPOND = 10
|
|
@@ -14,18 +17,27 @@ module DRbQS
|
|
|
14
17
|
# :continue
|
|
15
18
|
def initialize(access_uri, opts = {})
|
|
16
19
|
@access_uri = access_uri
|
|
17
|
-
@logger = DRbQS::
|
|
20
|
+
@logger = DRbQS::Misc.create_logger(opts[:log_file] || DEFAULT_LOG_FILE, opts[:log_level])
|
|
18
21
|
@connection = nil
|
|
19
22
|
@task_client = nil
|
|
20
23
|
@process_continue = opts[:continue]
|
|
21
24
|
@signal_queue = Queue.new
|
|
25
|
+
@config = DRbQS::Config.new
|
|
22
26
|
end
|
|
23
27
|
|
|
24
28
|
def transfer_file
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
+
if files = DRbQS::FileTransfer.dequeue_all
|
|
30
|
+
if @transfer
|
|
31
|
+
begin
|
|
32
|
+
@transfer.transfer(files, server_on_same_host?)
|
|
33
|
+
rescue => err
|
|
34
|
+
@logger.error("Fail to transfer files.") do
|
|
35
|
+
"Can not send file: #{files.join(", ")}\n#{err.to_s}\n#{err.backtrace.join("\n")}"
|
|
36
|
+
end
|
|
37
|
+
raise
|
|
38
|
+
end
|
|
39
|
+
else
|
|
40
|
+
raise "Server does not set transfer settings. Can not send file: #{files.join(", ")}"
|
|
29
41
|
end
|
|
30
42
|
end
|
|
31
43
|
end
|
|
@@ -34,19 +46,30 @@ module DRbQS
|
|
|
34
46
|
def execute_task(marshal_obj, method_sym, args)
|
|
35
47
|
result = DRbQS::Task.execute_task(marshal_obj, method_sym, args)
|
|
36
48
|
transfer_file
|
|
49
|
+
DRbQS::Temporary.delete
|
|
37
50
|
result
|
|
38
51
|
end
|
|
39
52
|
private :execute_task
|
|
40
53
|
|
|
54
|
+
def node_data
|
|
55
|
+
{ :uri => @access_uri }
|
|
56
|
+
end
|
|
57
|
+
private :node_data
|
|
58
|
+
|
|
41
59
|
def connect
|
|
42
60
|
obj = DRbObject.new_with_uri(@access_uri)
|
|
43
|
-
@
|
|
44
|
-
|
|
45
|
-
@task_client = TaskClient.new(
|
|
61
|
+
@server_key = obj[:key]
|
|
62
|
+
@connection = Node::Connection.new(obj[:message], @logger)
|
|
63
|
+
@task_client = Node::TaskClient.new(@connection.node_number, obj[:queue], obj[:result], @logger)
|
|
46
64
|
@transfer = obj[:transfer]
|
|
47
65
|
if ary = @connection.get_initialization
|
|
48
66
|
execute_task(*ary)
|
|
49
67
|
end
|
|
68
|
+
@config.list.node.save(Process.pid, node_data)
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
def server_on_same_host?
|
|
72
|
+
@config.list.server.server_of_key_exist?(@access_uri, @server_key)
|
|
50
73
|
end
|
|
51
74
|
|
|
52
75
|
def dump_not_send_result_to_file
|
|
@@ -58,9 +81,7 @@ module DRbQS
|
|
|
58
81
|
private :dump_not_send_result_to_file
|
|
59
82
|
|
|
60
83
|
def output_error(err, mes)
|
|
61
|
-
|
|
62
|
-
@logger.error("#{mes}: #{err.to_s}") { "\n" + err.backtrace.join("\n") }
|
|
63
|
-
end
|
|
84
|
+
@logger.error("#{mes}: #{err.to_s}") { "\n" + err.backtrace.join("\n") }
|
|
64
85
|
end
|
|
65
86
|
private :output_error
|
|
66
87
|
|
|
@@ -88,15 +109,18 @@ module DRbQS
|
|
|
88
109
|
private :send_error
|
|
89
110
|
|
|
90
111
|
def communicate_with_server
|
|
112
|
+
flag_finilize_exit = false
|
|
91
113
|
@task_client.add_new_task
|
|
92
114
|
case @connection.respond_signal
|
|
93
115
|
when :exit
|
|
94
116
|
return nil
|
|
95
117
|
when :finalize
|
|
96
|
-
|
|
97
|
-
|
|
118
|
+
flag_finilize_exit = true
|
|
119
|
+
when :exit_after_task
|
|
120
|
+
@task_client.set_exit_after_task
|
|
121
|
+
@process_continue = nil
|
|
98
122
|
end
|
|
99
|
-
@task_client.send_result
|
|
123
|
+
flag_finilize_exit = @task_client.send_result
|
|
100
124
|
until @signal_queue.empty?
|
|
101
125
|
signal, obj = @signal_queue.pop
|
|
102
126
|
case signal
|
|
@@ -105,7 +129,11 @@ module DRbQS
|
|
|
105
129
|
process_exit
|
|
106
130
|
end
|
|
107
131
|
end
|
|
108
|
-
|
|
132
|
+
if flag_finilize_exit
|
|
133
|
+
execute_finalization
|
|
134
|
+
return nil
|
|
135
|
+
end
|
|
136
|
+
true
|
|
109
137
|
end
|
|
110
138
|
private :communicate_with_server
|
|
111
139
|
|
|
@@ -120,6 +148,8 @@ module DRbQS
|
|
|
120
148
|
begin
|
|
121
149
|
loop do
|
|
122
150
|
unless communicate_with_server
|
|
151
|
+
DRbQS::Temporary.delete_all
|
|
152
|
+
@config.list.node.delete(Process.pid)
|
|
123
153
|
break
|
|
124
154
|
end
|
|
125
155
|
sleep(WAIT_NEW_TASK)
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
module DRbQS
|
|
2
|
+
class Node
|
|
3
|
+
class TaskClient
|
|
4
|
+
attr_reader :node_number, :calculating_task
|
|
5
|
+
|
|
6
|
+
def initialize(node_number, queue, result, logger = DRbQS::LoggerDummy.new)
|
|
7
|
+
@node_number = node_number
|
|
8
|
+
@queue = queue
|
|
9
|
+
@result = result
|
|
10
|
+
@calculating_task = nil
|
|
11
|
+
@exit_after_task = nil
|
|
12
|
+
@task_queue = Queue.new
|
|
13
|
+
@result_queue = Queue.new
|
|
14
|
+
@logger = logger
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def calculating?
|
|
18
|
+
!!@calculating_task
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def task_empty?
|
|
22
|
+
@task_queue.empty?
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def result_empty?
|
|
26
|
+
@result_queue.empty?
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def dequeue_result
|
|
30
|
+
@result_queue.deq
|
|
31
|
+
end
|
|
32
|
+
private :dequeue_result
|
|
33
|
+
|
|
34
|
+
def queue_task(task_id, ary)
|
|
35
|
+
@calculating_task = task_id
|
|
36
|
+
@task_queue.enq(ary)
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def dequeue_task
|
|
40
|
+
@task_queue.deq
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def get_task
|
|
44
|
+
begin
|
|
45
|
+
@queue.take([Fixnum, nil, Symbol, nil], 0)
|
|
46
|
+
rescue Rinda::RequestExpiredError
|
|
47
|
+
nil
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def set_exit_after_task
|
|
52
|
+
@exit_after_task = true
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def add_new_task
|
|
56
|
+
if !@calculating_task && !@exit_after_task
|
|
57
|
+
if ary = get_task
|
|
58
|
+
task_id, obj, method_sym, args = ary
|
|
59
|
+
@logger.info("Send accept signal: node #{@node_number} caluclating #{task_id}")
|
|
60
|
+
@result.write([:accept, task_id, @node_number])
|
|
61
|
+
queue_task(task_id, [obj, method_sym, args])
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
# If the method return true, a node should finilize and exit.
|
|
67
|
+
def send_result
|
|
68
|
+
if !result_empty?
|
|
69
|
+
result = dequeue_result
|
|
70
|
+
@logger.info("Send result: #{@calculating_task}") { result.inspect }
|
|
71
|
+
@result.write([:result, @calculating_task, @node_number, result])
|
|
72
|
+
@calculating_task = nil
|
|
73
|
+
end
|
|
74
|
+
!@calculating_task && @exit_after_task
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
def queue_result(result)
|
|
78
|
+
@result_queue.enq(result)
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
def dump_result_queue
|
|
82
|
+
results = []
|
|
83
|
+
while !result_empty?
|
|
84
|
+
results << dequeue_result
|
|
85
|
+
end
|
|
86
|
+
if results.size > 0
|
|
87
|
+
Marshal.dump(results)
|
|
88
|
+
else
|
|
89
|
+
nil
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
end
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
module DRbQS
|
|
2
|
+
class Server
|
|
3
|
+
module ACLFile
|
|
4
|
+
|
|
5
|
+
# Create ACL object from file.
|
|
6
|
+
# The example of file is the following:
|
|
7
|
+
# deny all
|
|
8
|
+
# allow localhost
|
|
9
|
+
# allow 127.0.0.1
|
|
10
|
+
def self.load(path)
|
|
11
|
+
ACL.new(File.read(path).split)
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
module DRbQS
|
|
2
|
+
class Server
|
|
3
|
+
class CheckAlive
|
|
4
|
+
DEFAULT_INTERVAL_TIME = 300
|
|
5
|
+
|
|
6
|
+
def initialize(interval)
|
|
7
|
+
@interval = interval || DEFAULT_INTERVAL_TIME
|
|
8
|
+
if !(Numeric === @interval) || @interval < 0
|
|
9
|
+
raise ArgumentError, "Invalid interval time."
|
|
10
|
+
end
|
|
11
|
+
@last = Time.now
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def significant_interval?
|
|
15
|
+
(Time.now - @last) >= @interval
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def set_checking
|
|
19
|
+
@last = Time.now
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
module DRbQS
|
|
2
|
+
class Server
|
|
3
|
+
|
|
4
|
+
# This class is used in DRbQS::Server::NodeList and DRbQS::Server::Queue to save some histories.
|
|
5
|
+
class History
|
|
6
|
+
include DRbQS::Misc
|
|
7
|
+
|
|
8
|
+
def initialize
|
|
9
|
+
@data = Hash.new { |h, k| h[k] = Array.new }
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def set(id, *args)
|
|
13
|
+
@data[id] << args.unshift(Time.now)
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def size
|
|
17
|
+
@data.size
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def events(id)
|
|
21
|
+
@data[id]
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def number_of_events(id)
|
|
25
|
+
@data[id].size
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def each(&block)
|
|
29
|
+
@data.each(&block)
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def log_strings
|
|
33
|
+
s = ''
|
|
34
|
+
each do |task_id, events|
|
|
35
|
+
s << "Task #{task_id}\n"
|
|
36
|
+
events.each do |ev|
|
|
37
|
+
case ev[1]
|
|
38
|
+
when :add, :requeue, :hook
|
|
39
|
+
s << " #{time_to_history_string(ev[0])}\t#{ev[1]}\n"
|
|
40
|
+
when :calculate, :result
|
|
41
|
+
s << " #{time_to_history_string(ev[0])}\t#{ev[1]} (node #{ev[2]})\n"
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
s
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|