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.
Files changed (96) hide show
  1. data/.document +3 -0
  2. data/README.md +137 -128
  3. data/VERSION +1 -1
  4. data/docs/FormatExecute.md +119 -0
  5. data/docs/GettingStarted.md +242 -0
  6. data/drbqs.gemspec +36 -13
  7. data/example/command/server_def.rb +4 -5
  8. data/example/execute/execute.rb +41 -0
  9. data/example/execute/server.rb +14 -0
  10. data/example/execute/task.rb +0 -0
  11. data/example/mandelbrot/README.md +15 -0
  12. data/example/mandelbrot/execute.rb +10 -0
  13. data/example/mandelbrot/mandelbrot.rb +56 -0
  14. data/example/mandelbrot/server.rb +49 -0
  15. data/example/server/server.rb +3 -6
  16. data/example/simple/README.md +18 -0
  17. data/example/simple/execute.rb +11 -0
  18. data/example/simple/server.rb +8 -0
  19. data/example/simple/task.rb +11 -0
  20. data/example/sum/server_def.rb +1 -1
  21. data/example/sum2/execute_def.rb +21 -8
  22. data/example/sum2/server_def.rb +8 -7
  23. data/example/transfer/file.rb +42 -8
  24. data/example/transfer/server_def.rb +43 -9
  25. data/lib/drbqs.rb +1 -1
  26. data/lib/drbqs/command_line/command_execute.rb +3 -3
  27. data/lib/drbqs/command_line/command_line.rb +1 -1
  28. data/lib/drbqs/execute/execute_node.rb +50 -0
  29. data/lib/drbqs/execute/process_define.rb +102 -54
  30. data/lib/drbqs/execute/register.rb +241 -87
  31. data/lib/drbqs/execute/server_define.rb +69 -58
  32. data/lib/drbqs/ext/task.rb +2 -0
  33. data/lib/drbqs/ext/task/command_task.rb +43 -0
  34. data/lib/drbqs/manage/manage.rb +5 -4
  35. data/lib/drbqs/manage/ssh_shell.rb +2 -8
  36. data/lib/drbqs/node/connection.rb +1 -1
  37. data/lib/drbqs/node/node.rb +8 -14
  38. data/lib/drbqs/node/task_client.rb +1 -1
  39. data/lib/drbqs/server/history.rb +5 -1
  40. data/lib/drbqs/server/message.rb +7 -34
  41. data/lib/drbqs/server/queue.rb +14 -2
  42. data/lib/drbqs/server/server.rb +86 -43
  43. data/lib/drbqs/server/server_hook.rb +3 -0
  44. data/lib/drbqs/server/test/node.rb +1 -1
  45. data/lib/drbqs/server/test/prof.rb +50 -0
  46. data/lib/drbqs/server/test/server.rb +2 -2
  47. data/lib/drbqs/server/transfer_setting.rb +23 -11
  48. data/lib/drbqs/setting/base.rb +15 -0
  49. data/lib/drbqs/setting/data_container.rb +1 -1
  50. data/lib/drbqs/setting/execute.rb +3 -3
  51. data/lib/drbqs/setting/node.rb +1 -1
  52. data/lib/drbqs/setting/server.rb +2 -2
  53. data/lib/drbqs/task/registrar.rb +39 -0
  54. data/lib/drbqs/task/task.rb +139 -59
  55. data/lib/drbqs/task/task_generator.rb +93 -116
  56. data/lib/drbqs/utility/misc.rb +15 -10
  57. data/lib/drbqs/utility/temporary.rb +7 -2
  58. data/lib/drbqs/utility/transfer/transfer.rb +81 -0
  59. data/lib/drbqs/utility/transfer/transfer_client.rb +68 -69
  60. data/lib/drbqs/utility/transfer/transfer_client_connect.rb +83 -0
  61. data/lib/drbqs/utility/transfer/transfer_file_list.rb +40 -0
  62. data/spec/execute/def/execute1.rb +4 -4
  63. data/spec/execute/def/execute2.rb +24 -0
  64. data/spec/execute/process_define_spec.rb +43 -6
  65. data/spec/execute/register_spec.rb +403 -9
  66. data/spec/execute/server_define_spec.rb +1 -1
  67. data/spec/ext/task/command_task_spec.rb +16 -0
  68. data/spec/integration_test/01_basic_usage_spec.rb +1 -1
  69. data/spec/integration_test/02_use_generator_spec.rb +2 -2
  70. data/spec/integration_test/04_use_unix_domain_spec.rb +1 -1
  71. data/spec/integration_test/05_server_exit_signal_spec.rb +1 -1
  72. data/spec/integration_test/06_node_exit_after_task_spec.rb +4 -4
  73. data/spec/integration_test/08_shutdown_unused_nodes_spec.rb +2 -2
  74. data/spec/integration_test/09_server_process_data_spec.rb +1 -1
  75. data/spec/integration_test/definition/server01.rb +4 -5
  76. data/spec/integration_test/definition/server02.rb +2 -4
  77. data/spec/node/node_spec.rb +34 -0
  78. data/spec/server/message_spec.rb +1 -1
  79. data/spec/server/queue_spec.rb +34 -7
  80. data/spec/server/server_spec.rb +21 -9
  81. data/spec/server/transfer_setting_spec.rb +59 -24
  82. data/spec/setting/base_spec.rb +11 -0
  83. data/spec/setting/data_container_spec.rb +8 -0
  84. data/spec/spec_helper.rb +1 -7
  85. data/spec/task/registrar_spec.rb +34 -0
  86. data/spec/task/task_generator_spec.rb +15 -15
  87. data/spec/task/task_spec.rb +132 -23
  88. data/spec/utility/misc_spec.rb +2 -2
  89. data/spec/utility/transfer/transfer_client_connect_spec.rb +90 -0
  90. data/spec/utility/transfer/transfer_file_list_spec.rb +27 -0
  91. data/spec/{task/file_transfer_spec.rb → utility/transfer/transfer_spec.rb} +24 -24
  92. metadata +66 -45
  93. data/lib/drbqs/manage/execute_node.rb +0 -50
  94. data/lib/drbqs/server/prof.rb +0 -48
  95. data/lib/drbqs/task/command_task.rb +0 -43
  96. data/lib/drbqs/utility/transfer/file_transfer.rb +0 -73
@@ -1,142 +1,119 @@
1
1
  module DRbQS
2
- class DRbQS::TaskCreatingError < StandardError
3
- end
4
-
5
- class TaskSource
6
- def initialize(data)
7
- data.each do |key, val|
8
- instance_variable_set("@#{key.to_s}", val)
2
+ class Task
3
+ class Generator
4
+ # @param [Hash] data Names of instance variables and their values,
5
+ # which can be accessed in {DRbQS::Task::Generator#set}.
6
+ def initialize(data = {})
7
+ @registrar = DRbQS::Task::Registrar.new(data)
8
+ @fiber = nil
9
+ @iterate = nil
10
+ @task_set = nil
11
+ @fiber_init = nil
12
+ @wait = false
9
13
  end
10
- end
11
14
 
12
- def add_task(arg)
13
- case arg
14
- when DRbQS::Task
15
- Fiber.yield(arg)
16
- when Array
17
- arg.each { |t| Fiber.yield(t) }
18
- else
19
- raise "Invalid type of an argument."
15
+ def have_next?
16
+ !!@fiber
20
17
  end
21
- end
22
18
 
23
- def create_add_task(*args, &block)
24
- add_task(DRbQS::Task.new(*args, &block))
25
- end
26
-
27
- def wait_all_tasks
28
- Fiber.yield(:wait)
29
- end
30
- end
31
-
32
- class TaskGenerator
33
- def initialize(data = {})
34
- @source = DRbQS::TaskSource.new(data)
35
- @fiber = nil
36
- @iterate = nil
37
- @task_set = nil
38
- @fiber_init = nil
39
- @wait = false
40
- end
41
-
42
- def have_next?
43
- !!@fiber
44
- end
45
-
46
- def waiting?
47
- @wait
48
- end
49
-
50
- # The options :generate and :collect are available.
51
- # opts[:generate] is the number of tasks per one generation.
52
- # The generator creates a task set from opts[:collect] tasks.
53
- def set(opts = {}, &block)
54
- @iterate = opts[:generate] || 1
55
- @task_set = opts[:collect]
56
- if @iterate < 1 || (@task_set && @task_set < 1)
57
- raise ArgumentError, "Invalid options of task creation on generator."
19
+ def waiting?
20
+ @wait
58
21
  end
59
- @fiber_init = lambda do
60
- @fiber = Fiber.new do
61
- begin
62
- @source.instance_eval(&block)
63
- rescue => err
64
- new_err = DRbQS::TaskCreatingError.new("#{err.to_s} (#{err.class}) when creating task")
65
- new_err.set_backtrace(err.backtrace)
66
- raise new_err
22
+
23
+ # @param [Hash] opts The options of task generation
24
+ # @option opts [Fixnum] :generate Set the number of tasks per one generation
25
+ # @option opts [Fixnum] :collect The generator creates a task set consisting of opts[:collect] tasks.
26
+ def set(opts = {}, &block)
27
+ unless block_given?
28
+ raise ArgumentError, "Creation of a task generator needs block."
29
+ end
30
+ @iterate = opts[:generate] || 1
31
+ @task_set = opts[:collect]
32
+ if @iterate < 1 || (@task_set && @task_set < 1)
33
+ raise ArgumentError, "Invalid options of task creation on generator."
34
+ end
35
+ @fiber_init = lambda do
36
+ @fiber = Fiber.new do
37
+ begin
38
+ @registrar.instance_eval(&block)
39
+ rescue => err
40
+ new_err = self.class.new("Error on generating tasks: #{err.to_s} (#{err.class})")
41
+ new_err.set_backtrace(err.backtrace)
42
+ raise new_err
43
+ end
44
+ nil
67
45
  end
68
- nil
69
46
  end
70
47
  end
71
- end
72
48
 
73
- # Initialize fider to create tasks.
74
- # This method must be called in thread to create tasks.
75
- def init
76
- @fiber_init.call if @fiber_init
77
- end
49
+ # Initialize fider to create tasks.
50
+ # This method must be called in thread to create tasks.
51
+ def init
52
+ @fiber_init.call if @fiber_init
53
+ end
78
54
 
79
- # Return an array of new tasks.
80
- def new_tasks
81
- if @fiber
82
- @wait = false
83
- task_ary = []
84
- iteration = @iterate
85
- iteration *= @task_set if @task_set
86
- iteration.times do |i|
87
- if task_new = @fiber.resume
88
- case task_new
89
- when DRbQS::Task
90
- task_ary << task_new
91
- when Array
92
- task_ary.concat(task_new)
93
- when :wait
94
- @wait = true
95
- break
55
+ # Return an array of new tasks.
56
+ def new_tasks
57
+ if @fiber
58
+ @wait = false
59
+ task_ary = []
60
+ iteration = @iterate
61
+ iteration *= @task_set if @task_set
62
+ iteration.times do |i|
63
+ if task_new = @fiber.resume
64
+ case task_new
65
+ when DRbQS::Task
66
+ task_ary << task_new
67
+ when Array
68
+ task_ary.concat(task_new)
69
+ when :wait
70
+ @wait = true
71
+ break
72
+ else
73
+ raise RuntimeError, "Invalid object created by fiber to create tasks."
74
+ end
96
75
  else
97
- raise "Invalid type of new task."
76
+ @fiber = nil
77
+ break
98
78
  end
99
- else
100
- @fiber = nil
101
- break
102
79
  end
103
- end
104
- if task_ary.size > 0
105
- if @task_set
106
- task_ary = task_ary.each_slice(@task_set).map do |ary|
107
- DRbQS::TaskSet.new(ary)
80
+ if task_ary.size > 0
81
+ if @task_set
82
+ task_ary = task_ary.each_slice(@task_set).map do |ary|
83
+ DRbQS::Task::TaskSet.new(ary)
84
+ end
108
85
  end
86
+ return task_ary
109
87
  end
110
- return task_ary
111
88
  end
89
+ nil
112
90
  end
113
- nil
114
- end
115
91
 
116
- DEBUG_TASK_PROGRESS = 1000
92
+ DEBUG_TASK_PROGRESS = 1000
117
93
 
118
- # Create all tasks for test and return [group_number, task_number] if all tasks created properly.
119
- def debug_all_tasks(opts = {})
120
- limit = opts[:limit]
121
- progress = opts[:progress]
122
- group_number = 0
123
- task_number = 0
124
- while ary = new_tasks
125
- ary.each do |t|
126
- unless DRbQS::Task === t
127
- raise "Invalid #{i}th task: #{t.inspect}"
128
- end
129
- task_number += 1
130
- if progress && (task_number % DEBUG_TASK_PROGRESS == 0)
131
- puts "#{task_number} tasks have been created."
132
- end
133
- if limit && task_number > limit
134
- break
94
+ # Create all tasks for test and return [group_number, task_number] if all tasks created properly.
95
+ def debug_all_tasks(opts = {})
96
+ limit = opts[:limit]
97
+ progress = opts[:progress]
98
+ group_number = 0
99
+ task_number = 0
100
+ while ary = new_tasks
101
+ ary.each do |t|
102
+ unless DRbQS::Task === t
103
+ raise RuntimeError, "Invalid #{i}th task: #{t.inspect}"
104
+ end
105
+ task_number += 1
106
+ if progress && (task_number % DEBUG_TASK_PROGRESS == 0)
107
+ puts "#{task_number} tasks have been created."
108
+ end
109
+ if limit && task_number > limit
110
+ break
111
+ end
135
112
  end
113
+ group_number += 1
136
114
  end
137
- group_number += 1
115
+ [group_number, task_number]
138
116
  end
139
- [group_number, task_number]
140
117
  end
141
118
  end
142
119
  end
@@ -1,21 +1,21 @@
1
1
  require 'sys/proctable'
2
2
 
3
3
  module DRbQS
4
- class LoggerDummy
5
- def info(*args)
6
- end
4
+ module Misc
5
+ class LoggerDummy
6
+ def info(*args)
7
+ end
7
8
 
8
- def warn(*args)
9
- end
9
+ def warn(*args)
10
+ end
10
11
 
11
- def error(*args)
12
- end
12
+ def error(*args)
13
+ end
13
14
 
14
- def debug(*args)
15
+ def debug(*args)
16
+ end
15
17
  end
16
- end
17
18
 
18
- module Misc
19
19
  # :port
20
20
  # :host
21
21
  # :unix
@@ -56,6 +56,11 @@ module DRbQS
56
56
  end
57
57
  module_function :time_to_history_string
58
58
 
59
+ def time_to_history_string2(t)
60
+ t.strftime("%m-%d %H:%M:%S")
61
+ end
62
+ module_function :time_to_history_string2
63
+
59
64
  STRINGS_FOR_KEY = ('a'..'z').to_a + ('A'..'Z').to_a + ('0'..'9').to_a
60
65
 
61
66
  def random_key(size = 20)
@@ -22,8 +22,13 @@ module DRbQS
22
22
  end
23
23
 
24
24
  # Return new path of temporary file.
25
- def self.file
26
- filename.create(:add => :always)
25
+ # @param [String] basename Set the basename of created filename
26
+ def self.file(basename = nil)
27
+ if basename
28
+ File.join(self.directory, basename)
29
+ else
30
+ filename.create(:add => :always)
31
+ end
27
32
  end
28
33
 
29
34
  # Make root of temporary directory empty.
@@ -0,0 +1,81 @@
1
+ module DRbQS
2
+ # To compress files, we use gzip and tar command.
3
+ # Note that if we compress files then we delete the original files.
4
+ class Transfer
5
+ @files = Queue.new
6
+
7
+ class << self
8
+ # Add path to queue of which files is going to be transfered to server.
9
+ # @param [String] path The file path that we want to send to a server.
10
+ # @param [Hash] opts The options for transfering a file.
11
+ # @option opts [true,false] :compress Compress the file by gzip before transfering.
12
+ # @option opts [String] :rename Change basename to the specified name.
13
+ def enqueue(path, opts = {})
14
+ if opts[:rename]
15
+ new_path = FileName.create(File.join(File.dirname(path), opts[:rename]), :directory => :parent)
16
+ FileUtils.mv(path, new_path)
17
+ path = new_path
18
+ end
19
+ if opts[:compress]
20
+ if File.directory?(path)
21
+ gz_path = "#{path.sub(/\/$/, '')}.tar.gz"
22
+ cmd = "tar czf #{gz_path} -C #{File.dirname(path)} #{File.basename(path)} > /dev/null 2>&1"
23
+ else
24
+ gz_path = path + '.gz'
25
+ cmd = "gzip --best #{path} > /dev/null 2>&1"
26
+ end
27
+ if File.exist?(gz_path)
28
+ raise "File has already existed: #{gz_path}"
29
+ elsif !system(cmd)
30
+ raise "Can not compress: #{path}"
31
+ end
32
+ FileUtils.rm_r(path) if File.exist?(path)
33
+ path_to_send = gz_path
34
+ else
35
+ path_to_send = path
36
+ end
37
+ @files.enq(path_to_send)
38
+ File.basename(path_to_send)
39
+ end
40
+
41
+ def compress_enqueue(path)
42
+ enqueue(path, :compress => true)
43
+ end
44
+
45
+ def dequeue
46
+ @files.deq
47
+ end
48
+
49
+ def empty?
50
+ @files.empty?
51
+ end
52
+
53
+ def dequeue_all
54
+ files = []
55
+ until empty?
56
+ files << dequeue
57
+ end
58
+ files.empty? ? nil : files
59
+ end
60
+
61
+ # Decompress a file in the file directory of a server.
62
+ # @param [DRbQS::Server] server Current server
63
+ # @param [String] filename File path to decompress
64
+ def decompress(server, filename)
65
+ dir = server.transfer_directory
66
+ path = File.join(dir, filename)
67
+ if File.exist?(path)
68
+ case path
69
+ when /\.tar\.gz$/
70
+ cmd = "tar xvzf #{path} -C #{dir} > /dev/null 2>&1"
71
+ when /\.gz$/
72
+ cmd = "gunzip #{path} > /dev/null 2>&1"
73
+ else
74
+ cmd = nil
75
+ end
76
+ system(cmd) if cmd
77
+ end
78
+ end
79
+ end
80
+ end
81
+ end
@@ -1,90 +1,89 @@
1
- require 'net/sftp'
1
+ require 'drbqs/utility/transfer/transfer_client_connect.rb'
2
2
 
3
3
  module DRbQS
4
+ class Transfer
5
+ class Client
6
+ attr_reader :directory, :local, :sftp
4
7
 
5
- class TransferClient
6
-
7
- class ClientBase
8
- def initialize(directory)
9
- @directory = File.expand_path(directory)
10
- end
11
-
12
- def upload_name(path)
13
- File.join(@directory, File.basename(path))
14
- end
15
- private :upload_name
16
- end
17
-
18
- # Transfer files to directory on DRbQS server over sftp.
19
- # Note that after we transfer files we delete the original files.
20
- class SFTP < DRbQS::TransferClient::ClientBase
21
- attr_reader :user, :host, :directory
22
-
23
- def initialize(user, host, directory)
24
- super(directory)
25
- @user = user
26
- @host = host
8
+ def initialize(server_directory, same_host, host, user)
9
+ unless Pathname.new(server_directory).absolute?
10
+ raise ArgumentError, "Directory of server must be absolute."
11
+ end
12
+ @directory = server_directory
13
+ @same_host = same_host
14
+ @local = DRbQS::Transfer::Client::Local.new(@directory)
15
+ if host && user
16
+ @sftp = DRbQS::Transfer::Client::SFTP.new(user, host, @directory)
17
+ else
18
+ @sftp = nil
19
+ end
27
20
  end
28
21
 
29
- # Transfer and delete +files+.
30
22
  def transfer(files)
31
- Net::SFTP.start(@host, @user) do |sftp|
32
- files.each do |path|
33
- sftp.upload(path, upload_name(path))
34
- FileUtils.rm_r(path)
23
+ transfered = false
24
+ if @same_host
25
+ begin
26
+ @local.transfer(files)
27
+ transfered = true
28
+ rescue
29
+ end
30
+ end
31
+ if !transfered
32
+ unless @sftp
33
+ raise "Can not transfer files."
35
34
  end
35
+ @sftp.transfer(files)
36
36
  end
37
- rescue => err
38
- raise err.class, "user=#{@user}, host=#{@host}, directory=#{@directory}; #{err.to_s}", err.backtrace
39
37
  end
40
- end
41
38
 
42
- class Local < DRbQS::TransferClient::ClientBase
43
- def transfer(files)
44
- files.each do |path|
45
- FileUtils.mv(path, upload_name(path))
39
+ def download(files, readonly = nil)
40
+ download_files = nil
41
+ if @same_host
42
+ begin
43
+ if readonly
44
+ download_files = files
45
+ else
46
+ download_files = @local.download(files)
47
+ end
48
+ rescue
49
+ end
46
50
  end
51
+ if !download_files
52
+ unless @sftp
53
+ raise "SFTP is not prepared."
54
+ end
55
+ download_files = @sftp.download(files)
56
+ end
57
+ download_files
47
58
  end
48
- end
49
-
50
- attr_reader :directory, :local, :sftp
51
-
52
- def initialize(dir)
53
- @directory = File.expand_path(dir)
54
- @local = DRbQS::TransferClient::Local.new(@directory)
55
- @sftp = nil
56
- end
57
-
58
- def make_directory
59
- FileUtils.mkdir_p(@directory)
60
- end
61
59
 
62
- def set_sftp(user, host)
63
- @sftp = DRbQS::TransferClient::SFTP.new(user, host, @directory)
64
- end
60
+ class << self
61
+ @transfer = nil
65
62
 
66
- def information
67
- info = "directory: #{@directory}"
68
- info << ", sftp: #{@sftp.user}@#{@sftp.host}" if @sftp
69
- info
70
- end
63
+ def get
64
+ @transfer
65
+ end
71
66
 
72
- def transfer(files, on_same_host = nil)
73
- transfered = false
74
- if on_same_host
75
- begin
76
- @local.transfer(files)
77
- transfered = true
78
- rescue
67
+ def set(transfer)
68
+ @transfer = transfer
79
69
  end
80
- end
81
- if !transfered
82
- unless @sftp
83
- raise "Can not transfer files."
70
+
71
+ def transfer_to_server
72
+ if files = DRbQS::Transfer.dequeue_all
73
+ if @transfer
74
+ begin
75
+ @transfer.transfer(files)
76
+ rescue Exception => err
77
+ err_new = err.class.new("#{err.to_s} (#{err.class}); Can not send file: #{files.join(", ")}")
78
+ err_new.set_backtrace(err.backtrace)
79
+ raise err_new
80
+ end
81
+ else
82
+ raise "Server does not set transfer settings. Can not send file: #{files.join(", ")}"
83
+ end
84
+ end
84
85
  end
85
- @sftp.transfer(files)
86
86
  end
87
87
  end
88
88
  end
89
-
90
89
  end