drbqs 0.0.15 → 0.0.16

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