drbqs 0.0.13 → 0.0.14

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