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.
Files changed (115) hide show
  1. data/Gemfile +10 -7
  2. data/README.md +52 -11
  3. data/Rakefile +32 -10
  4. data/VERSION +1 -1
  5. data/bin/drbqs-manage +3 -93
  6. data/bin/drbqs-node +3 -89
  7. data/bin/drbqs-server +3 -117
  8. data/bin/drbqs-ssh +6 -0
  9. data/drbqs.gemspec +118 -97
  10. data/example/README.md +2 -2
  11. data/lib/drbqs/config/config.rb +88 -0
  12. data/lib/drbqs/config/process_list.rb +194 -0
  13. data/lib/drbqs/config/ssh_host.rb +41 -0
  14. data/lib/drbqs/{execute_node.rb → manage/execute_node.rb} +6 -4
  15. data/lib/drbqs/manage/manage.rb +100 -0
  16. data/lib/drbqs/manage/send_signal.rb +45 -0
  17. data/lib/drbqs/manage/ssh_execute.rb +23 -0
  18. data/lib/drbqs/manage/ssh_shell.rb +143 -0
  19. data/lib/drbqs/node/connection.rb +69 -0
  20. data/lib/drbqs/{client.rb → node/node.rb} +48 -18
  21. data/lib/drbqs/node/task_client.rb +94 -0
  22. data/lib/drbqs/server/acl_file.rb +15 -0
  23. data/lib/drbqs/server/check_alive.rb +23 -0
  24. data/lib/drbqs/server/history.rb +49 -0
  25. data/lib/drbqs/server/message.rb +142 -0
  26. data/lib/drbqs/server/node_list.rb +59 -0
  27. data/lib/drbqs/server/queue.rb +128 -0
  28. data/lib/drbqs/{server.rb → server/server.rb} +66 -74
  29. data/lib/drbqs/server/server_hook.rb +72 -0
  30. data/lib/drbqs/server/transfer_setting.rb +30 -0
  31. data/lib/drbqs/task/command_task.rb +43 -0
  32. data/lib/drbqs/{task.rb → task/task.rb} +18 -39
  33. data/lib/drbqs/{task_generator.rb → task/task_generator.rb} +2 -0
  34. data/lib/drbqs/utility/argument.rb +27 -0
  35. data/lib/drbqs/utility/command_line/command_base.rb +27 -0
  36. data/lib/drbqs/utility/command_line/command_manage.rb +121 -0
  37. data/lib/drbqs/utility/command_line/command_node.rb +103 -0
  38. data/lib/drbqs/utility/command_line/command_server.rb +165 -0
  39. data/lib/drbqs/utility/command_line/command_ssh.rb +126 -0
  40. data/lib/drbqs/utility/command_line.rb +15 -0
  41. data/lib/drbqs/utility/misc.rb +72 -0
  42. data/lib/drbqs/{server_define.rb → utility/server_define.rb} +23 -8
  43. data/lib/drbqs/utility/temporary.rb +49 -0
  44. data/lib/drbqs/{ssh/transfer.rb → utility/transfer/file_transfer.rb} +18 -58
  45. data/lib/drbqs/utility/transfer/transfer_client.rb +90 -0
  46. data/lib/drbqs.rb +10 -22
  47. data/spec/config/config_spec.rb +84 -0
  48. data/spec/config/process_list_spec.rb +149 -0
  49. data/spec/config/ssh_host_spec.rb +81 -0
  50. data/spec/integration_test/01_basic_usage_spec.rb +54 -0
  51. data/spec/integration_test/02_use_generator_spec.rb +53 -0
  52. data/spec/integration_test/03_use_temporary_file_spec.rb +26 -0
  53. data/spec/integration_test/04_use_unix_domain_spec.rb +34 -0
  54. data/spec/integration_test/05_server_exit_signal_spec.rb +23 -0
  55. data/spec/integration_test/06_node_exit_after_task_spec.rb +42 -0
  56. data/spec/integration_test/07_command_server_with_node_spec.rb +44 -0
  57. data/spec/integration_test/definition/server01.rb +20 -0
  58. data/spec/integration_test/definition/server02.rb +16 -0
  59. data/spec/integration_test/definition/task_obj_definition.rb +49 -0
  60. data/spec/manage/manage_spec.rb +33 -0
  61. data/spec/manage/send_signal_spec.rb +39 -0
  62. data/spec/{ssh_shell_spec.rb → manage/ssh_shell_spec.rb} +8 -8
  63. data/spec/node/connection_spec.rb +66 -0
  64. data/spec/node/task_client_spec.rb +212 -0
  65. data/spec/server/acl_file_spec.rb +9 -0
  66. data/spec/{server_check_alive_spec.rb → server/check_alive_spec.rb} +15 -11
  67. data/spec/{data → server/data}/acl.txt +0 -0
  68. data/spec/{history_spec.rb → server/history_spec.rb} +9 -5
  69. data/spec/server/message_spec.rb +195 -0
  70. data/spec/server/node_list_spec.rb +111 -0
  71. data/spec/server/queue_spec.rb +239 -0
  72. data/spec/{server_hook_spec.rb → server/server_hook_spec.rb} +23 -17
  73. data/spec/server/server_spec.rb +89 -0
  74. data/spec/server/transfer_setting_spec.rb +37 -0
  75. data/spec/spec_helper.rb +65 -0
  76. data/spec/task/file_transfer_spec.rb +107 -0
  77. data/spec/{task_generator_spec.rb → task/task_generator_spec.rb} +2 -2
  78. data/spec/{task_spec.rb → task/task_spec.rb} +3 -1
  79. data/spec/utility/argument_spec.rb +39 -0
  80. data/spec/utility/command_line/command_base_spec.rb +33 -0
  81. data/spec/utility/command_line/commands_spec.rb +15 -0
  82. data/spec/utility/misc_spec.rb +77 -0
  83. data/spec/utility/server_define_spec.rb +59 -0
  84. data/spec/utility/temporary_spec.rb +39 -0
  85. metadata +158 -93
  86. data/example/drbqs-manage-test.rb +0 -3
  87. data/example/drbqs-node-test.rb +0 -3
  88. data/example/drbqs-server-test.rb +0 -3
  89. data/lib/drbqs/acl_file.rb +0 -13
  90. data/lib/drbqs/config.rb +0 -98
  91. data/lib/drbqs/connection.rb +0 -67
  92. data/lib/drbqs/history.rb +0 -34
  93. data/lib/drbqs/manage.rb +0 -84
  94. data/lib/drbqs/message.rb +0 -119
  95. data/lib/drbqs/node_list.rb +0 -52
  96. data/lib/drbqs/queue.rb +0 -138
  97. data/lib/drbqs/server_hook.rb +0 -67
  98. data/lib/drbqs/ssh/host.rb +0 -26
  99. data/lib/drbqs/ssh/shell.rb +0 -139
  100. data/lib/drbqs/task_client.rb +0 -86
  101. data/lib/drbqs/utils.rb +0 -19
  102. data/spec/acl_file_spec.rb +0 -9
  103. data/spec/config_spec.rb +0 -14
  104. data/spec/connection_spec.rb +0 -49
  105. data/spec/manage_spec.rb +0 -57
  106. data/spec/message_spec.rb +0 -81
  107. data/spec/node_list_spec.rb +0 -68
  108. data/spec/queue_spec.rb +0 -59
  109. data/spec/server_define_spec.rb +0 -45
  110. data/spec/server_spec.rb +0 -56
  111. data/spec/task_client_spec.rb +0 -53
  112. data/spec/test/test1.rb +0 -13
  113. data/spec/test1_spec.rb +0 -80
  114. data/spec/test2_spec.rb +0 -69
  115. 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/connection'
2
- require 'drbqs/task_client'
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 Client
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::Utils.create_logger(opts[:log_file] || DEFAULT_LOG_FILE, opts[:log_level])
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
- until FileTransfer.empty?
26
- path = FileTransfer.dequeue
27
- unless @transfer.scp(path)
28
- raise "Can not send file: #{path}"
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
- @connection = ConnectionClient.new(obj[:message], @logger)
44
- node_id = @connection.get_id
45
- @task_client = TaskClient.new(node_id, obj[:queue], obj[:result], @logger)
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
- if @logger
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
- execute_finalization
97
- return nil
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
- return true
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