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
data/.document CHANGED
@@ -1,5 +1,8 @@
1
+ -m
2
+ markdown
1
3
  lib/**/*.rb
2
4
  bin/*
3
5
  -
4
6
  features/**/*.feature
5
7
  LICENSE.txt
8
+ docs/**/*.md
data/README.md CHANGED
@@ -1,180 +1,189 @@
1
- # drbqs
1
+ # DRbQS
2
2
 
3
3
  Task queuing system over network that is implemented by dRuby.
4
+ Tasks created by a server are distributed to nodes for calculation.
5
+
6
+ - [http://rubygems.org/gems/drbqs](http://rubygems.org/gems/drbqs)
7
+ - [https://github.com/ytaka/drbqs](https://github.com/ytaka/drbqs)
4
8
 
5
9
  ## Summary
6
10
 
7
- To use DRbQS, first, we start a server of DRbQS.
8
- Second, we execute nodes (on same host or other hosts)
9
- loading libraries required by the server
10
- and connect the nodes to the server.
11
-
12
- The behavior of nodes requests tasks, gets tasks from a server, processes the tasks,
13
- and sends results of the tasks to the server.
14
- The nodes work repeatedly until they get exit signal from server.
15
- The server prepares tasks and signals to check that nodes are alive.
16
- If the server does not communicate with the nodes unexpectedly,
17
- the server deletes the nodes from node list and
18
- requeues their calculating tasks.
19
- We can set hooks for tasks.
20
- The hooks are executed for results of the tasks
21
- after the server accepts them from nodes.
22
-
23
- The tasks are made from objects, an instance method of them, and its arguments.
24
- Because we use Marshal.dump and Marshal.load for communication of a server and nodes,
25
- the objects and the arguments must be marshalized.
26
- And also we tell the server and the nodes the definition of class of the objects and the arguments.
27
-
28
- ## Requirements
11
+ DRbQS is written as server-client system;
12
+ a server creates tasks and puts them into Rinda::TupleSpace;
13
+ nodes for calculation take tasks from Rinda::TupleSpace, calculate them,
14
+ and return their results to the server.
15
+
16
+ DRbQS also provides some utilities to define tasks,
17
+ to execute a server and nodes (over ssh),
18
+ to transfer files between a server and nodes,
19
+ to create temporary files and directories,
20
+ and to test and profile programs of DRbQS.
21
+
22
+ DRbQS is tested on Ubuntu 11.04 and
23
+ we can install DRbQS easily on Linux.
24
+ Note that due to some requirements, DRbQS does not work probably on Windows.
25
+
26
+ ## Requirements & Installation
27
+
28
+ We can install gem of DRbQS.
29
+
30
+ gem install drbqs
29
31
 
30
32
  DRbQS uses Fiber, so ruby requires version 1.9.
31
- And we use net-ssh and net-ssh-shell to execute servers and nodes over ssh.
33
+ Also, some features of DRbQS does not work on Windows platform
34
+ due to uses of Kernel#fork.
35
+ Because SSH is used to execute processes over network,
36
+ it is desirable that ssh servers on all computers are installed.
32
37
 
33
- ## Usage
38
+ DRbQS requires the following gems.
34
39
 
35
- ### Preparation
40
+ - [filename](http://rubygems.org/gems/filename)
41
+ - [net-sftp](http://rubygems.org/gems/net-sftp)
42
+ - [net-ssh](http://rubygems.org/gems/net-ssh)
43
+ - [net-ssh-shell](http://rubygems.org/gems/net-ssh-shell)
44
+ - [sys-proctable](http://rubygems.org/gems/sys-proctable)
45
+ - [user_config](http://rubygems.org/gems/user_config)
36
46
 
37
- We prepare a class to send tasks over network,
38
- which has data and a method to deal with tasks.
47
+ If we want to profile programs for DRbQS
48
+ then we need to install [ruby-prof](http://rubygems.org/gems/ruby-prof).
39
49
 
40
- For example, we make sum.rb as the following.
50
+ gem install ruby-prof
41
51
 
42
- class Sum
43
- def initialize(start_num, end_num)
44
- @num = [start_num, end_num]
45
- end
46
-
47
- def exec
48
- (@num[0]..@num[1]).inject(0) { |sum, i| sum += i }
49
- end
50
- end
52
+ DRbQS saves configuration files in ~/.drbqs.
53
+ To create the directory, we type in a terminal
51
54
 
52
- The Sum class calculates sum of numbers from start_num to end_num.
53
- The task we want to calculate is summation of numbers.
55
+ drbqs-manage initialize
54
56
 
55
- ### Start server
57
+ ## Explanation of DRbQS
56
58
 
57
- We make server.rb as the following.
59
+ ### Server of DRbQS
58
60
 
59
- require_relative 'sum.rb'
60
-
61
- DRbQS.define_server(:finish_exit => true) do |server, argv, opts|
62
- 10.step(100, 10) do |i|
63
- task = DRbQS::Task.new(Sum.new(i - 10, i), :exec)
64
- server.queue.add(task)
65
- end
66
- end
61
+ A server works as below.
67
62
 
68
- In terminal, we load server.rb and execute server of drbqs.
63
+ 1. Initialization
64
+ 2. Check message from user or nodes
65
+ 3. Check connection of nodes
66
+ 4. Process result data from nodes
67
+ 5. Execute some methods (which is called 'hook')
68
+ - Process string data sent from user
69
+ - Add new tasks if queue of the server is empty
70
+ - and so on
71
+ 6. Repeat 2-5 until all tasks are finished
72
+ 7. Send finalization signals to nodes
73
+ 8. Wait nodes exiting
74
+ 9. Exit
69
75
 
70
- drbqs-server server.rb -p 13500
76
+ ### Node of DRbQS
71
77
 
72
- ### Hook of server
78
+ A node works as below.
73
79
 
74
- We can use two hooks of server: 'empty_queue' and 'finish'.
80
+ 1. Connect to a server, takes an initialization task from the serve,
81
+ and execute it
82
+ 2. Create two threads: connection of server and calculation of tasks
83
+ 3. Thread of connection checks signals from a server by an interval time
84
+ and get new task if there is no calculating task
85
+ 4. Thread of calculation processes a task
86
+ 5. Receiving a finalization signal, the node exits
75
87
 
76
- DRbQS.define_server do |server, argv, opts|
77
- server.add_hook(:empty_queue) do |srv|
78
- srv.queue.add( ... )
79
- end
80
-
81
- server.add_hook(:finish) do |srv|
82
- srv.exit
83
- end
84
- end
88
+ ## Commands of DRbQS
85
89
 
86
- 'finish' hook usually exit server program, but
87
- an option :finish_exit for DRbQS.define_server or DRbQS.new
88
- is nearly same.
90
+ ### drbqs-server
89
91
 
90
- We can use 'empty_queue' hook for adding tasks
91
- when task queue is empty.
92
+ Execute a server from a file in which the creation of tasks is written.
92
93
 
93
- ### Task generator
94
+ ### drbqs-node
94
95
 
95
- Arguments of DRbQS::TaskGenerator.new define instance variables,
96
- which is implemented by Fiber and is executed by server's requests.
96
+ Specifying a file that defines class of tasks,
97
+ execute nodes to connect the server.
97
98
 
98
- task_generator = DRbQS::TaskGenerator.new(:abc => 'ABC', :def => 123, :data => [1, 2, 3])
99
+ ### drbqs-manage
99
100
 
100
- The above example defines the following instance variables.
101
+ Send some signals to a server and get some information.
101
102
 
102
- @abc = 'ABC'
103
- @def = 123
104
- @data = [1, 2, 3]
103
+ ### drbqs-ssh
105
104
 
106
- Then, DRbQS::TaskGenerator#set method defines generation of tasks.
107
- The block of the method is evaluated in the context of task_generator.
108
- We can use @abc, @def, and @data on the above example.
105
+ Run processes of a server and a node over ssh.
109
106
 
110
- task_generator.set do
111
- @data.each do |i|
112
- create_add_task(i, :to_s)
113
- end
114
- end
107
+ ### drbqs-execute
115
108
 
116
- DRbQS::TaskGenerator#create_add_task set a task
117
- and DRbQS::TaskGenerator#new_tasks actually creates the task.
118
- The arguments of DRbQS::TaskGenerator#create_add_task is
119
- the same as DRbQS::Task.new.
109
+ Execute set of a server and nodes from a file written as DSL,
110
+ which can be over SSH.
120
111
 
121
- To use the generator in DRbQS::Server,
122
- we set the generator by DRbQS::Server#add_task_generator.
112
+ ## Simple example
123
113
 
124
- ### Start node and connect server
114
+ ### Files
125
115
 
126
- Because nodes need class Sum,
127
- the nodes load sum.rb when they starts.
128
- Then, we use '-l' option for command 'drbqs-node'.
129
- That is, we type in terminal.
116
+ - **server.rb** : Definition of server
117
+ - **task.rb** : Class of tasks
118
+ - **execute.rb** : DSL to start processes.
130
119
 
131
- drbqs-node druby://localhost:13500/ -l sum.rb
120
+ The above examples are in the directory example/simple.
132
121
 
133
- We execute two processes to use two CPU cores.
122
+ ### server.rb
134
123
 
135
- drbqs-node 2 druby://localhost:13500/ -l sum.rb
124
+ require_relative 'task.rb'
125
+
126
+ DRbQS.define_server do |server, argv, opts|
127
+ task = DRbQS::Task.new(Sum.new(10, 20, 2), :calc) do |srv, result|
128
+ puts "Result is #{result}"
129
+ end
130
+ server.queue.add(task)
131
+ end
132
+
133
+ ### task.rb
134
+
135
+ class Sum
136
+ def initialize(a, b, c)
137
+ @a = a
138
+ @b = b
139
+ @c = c
140
+ end
141
+
142
+ def calc
143
+ @a + @b + @c
144
+ end
145
+ end
136
146
 
137
- Then, if it succeeds, the calculation starts.
138
- If it finishes, the server and node end.
147
+ ### execute.rb
139
148
 
140
- ## Provided task
149
+ DIR = File.dirname(__FILE__)
150
+
151
+ default port: 12345
152
+
153
+ server :local, "localhost" do |srv|
154
+ srv.load File.join(DIR, 'server.rb')
155
+ end
156
+
157
+ node :local do |nd|
158
+ nd.load File.join(DIR, 'task.rb')
159
+ end
141
160
 
142
- ### DRbQS::Task
161
+ ### drbqs-server and drbqs-node
143
162
 
144
- DRbQS::Task is the basic class to define tasks of DRbQS,
145
- whose objects are consisted of a object having method to process a task
146
- and hook for returned result.
147
- Basically, we define objects of DRbQS::Task and
148
- give the objects to a server.
163
+ Basic way of execution is how to use the commands drbqs-server and drbqs-node.
164
+ We move the same directory of server.rb and task.rb in a terminal.
165
+ To execute a server, we type the command
149
166
 
150
- ### DRbQS::TaskSet
167
+ drbqs-server server.rb
151
168
 
152
- DRbQS::TaskSet is a child class of DRbQS::Task and consists of group a number of tasks.
153
- Objects of the class are generated when we set the option :collect to DRbQS::TaskGenerator#set
154
- and therefore we are unaware of the objects of DRbQS::TaskSet
155
- in many cases.
169
+ To execute a node, we type the command in another terminal
156
170
 
157
- ### DRbQS::CommandTask
171
+ drbqs-node druby://:13500 -l task.rb
158
172
 
159
- DRbQS::CommandTask is a class to create tasks to execute some command.
173
+ Then, the node connects to the server and calculate a task.
174
+ When the node send the result of the task,
175
+ the result of sum is displayed in the terminal of the server.
160
176
 
161
- ## Temporary file
177
+ ### drbqs-execute
162
178
 
163
- We can use temporary directories and files on nodes.
164
- In methods to calculate tasks,
165
- DRbQS::Temporary.file returns a name of temporary file and
166
- DRbQS::Temporary.directory returns a name of temporary directory.
167
- These temporary files and directories are deleted
168
- after the task is completed.
179
+ To run a server and some nodes all together,
180
+ we uses the command drbqs-execute and a definition file.
181
+ In the same directory of execute.rb, we type the command
169
182
 
170
- ## File transfer
183
+ drbqs-execute execute.rb
171
184
 
172
- When a task is finished on a node,
173
- we can transfer files from a server to a client.
174
- To be more precise, we enqueue a file by DRbQS::FileTransfer.enqueue
175
- in methods to calculate tasks and
176
- files in the queue are automatically transferred.
177
- Then, original files on nodes are deleted after transferring.
185
+ Then, a server and a node run and
186
+ their output is saved to files in the directory 'drbqs\_execute\_log'.
178
187
 
179
188
  ## Contributing to drbqs
180
189
 
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.0.15
1
+ 0.0.16
@@ -0,0 +1,119 @@
1
+ # Format of File for drbqs-execute
2
+
3
+ ## Outline
4
+
5
+ drbqs-execute evaluates files in the context of an object of
6
+ {DRbQS::ProcessDefinition::Register}.
7
+ Therefore, we can use methods of {DRbQS::ProcessDefinition::Register}
8
+ in files given to drbqs-execute.
9
+
10
+ drbqs-execute execute a server of which uri is made from hostname and port.
11
+ Moreover, drbqs-execute make nodes connecting to the uri of server.
12
+ The server and nodes can be over SSH.
13
+
14
+ ## Example: execute.rb
15
+
16
+ #!/usr/bin/env drbqs-execute
17
+ # -*-ruby-*-
18
+
19
+ usage message: "Message of this file", server: File.join(File.dirname(__FILE__), 'server.rb')
20
+
21
+ default server: :server1, port: 12345, node: [:node1, :node3, :node5], log: "/tmp/drbqs/log"
22
+
23
+ ssh_directory = "/ssh/path/to"
24
+
25
+ server :server1, 'example.com' do |server, ssh|
26
+ ssh.directory ssh_directory
27
+ ssh.output "/path/to/log"
28
+ ssh.nice 5
29
+ server.load "server.rb"
30
+ server.log_level 'error'
31
+ end
32
+
33
+ server :local, 'localhost' do |server|
34
+ server.load "server.rb"
35
+ server.log_level 'error'
36
+ end
37
+
38
+ node :node_base, template: true do |node, ssh|
39
+ ssh.directory ssh_directory
40
+ ssh.output "/path/to/node_ssh"
41
+ ssh.nice 10
42
+ node.process 2
43
+ node.load "server.rb"
44
+ node.log_level 'error'
45
+ end
46
+
47
+ ssh_user = 'user_name'
48
+ [1, 2, 3, 4, 5, 6].each do |n|
49
+ name = "node%02d" % n
50
+ node name, load: :node_base do |node, ssh|
51
+ ssh.connect "#{ssh_user}@#{name}.example.com"
52
+ end
53
+ end
54
+
55
+ node :even, group: [:node02, :node04, :node06]
56
+ node :odd, group: [:node01, :node03, :node05]
57
+
58
+ ## Help message
59
+
60
+ If we run the following command
61
+
62
+ drbqs-execute -h execute.rb
63
+
64
+ then help message of server.rb is displayed in addition to that of drbqs-execute.
65
+
66
+ ## Methods
67
+
68
+ The following methods are available.
69
+
70
+ ### server
71
+
72
+ "server" method corresponds to commands "drbqs-server" and "drbqs-ssh server".
73
+ This method takes two arguments (server name and hostname),
74
+ options set by hash and a block.
75
+ If the block takes only one argument then the server is on localhost.
76
+ If there are two block arguments then the server is executed over SSH.
77
+ The first argument of block has methods similar to
78
+ the options of command "drbqs-server".
79
+ The second argument has methods similar to the options of command "drbqs-ssh".
80
+ We can set the settings of servers by these methods.
81
+
82
+ See {DRbQS::ProcessDefinition::Register#server}
83
+
84
+ ### node
85
+
86
+ "node" method corresponds to commands "drbqs-node" and "drbqs-ssh node",
87
+ which takes node name and options set by hash as arguments.
88
+ As the same way of method "server" we can define nodes by method "node"
89
+ The block taking one argument defines a node on localhost and
90
+ the block taking two arguments defines a node over SSH.
91
+ The first argument has methods similar to the options of command "drbqs-node" and
92
+ the second argument has methods similar to the options of command "drbqs-ssh".
93
+
94
+ See {DRbQS::ProcessDefinition::Register#node}
95
+
96
+ ### clear\_server
97
+
98
+ See {DRbQS::ProcessDefinition::Register#clear\_server}
99
+
100
+ ### clear\_node
101
+
102
+ See {DRbQS::ProcessDefinition::Register#clear\_node}
103
+
104
+ ### default
105
+
106
+ We can set default server, default nodes, default port number of server
107
+ by method "default".
108
+
109
+ See {DRbQS::ProcessDefinition::Register#default}
110
+
111
+ ### default_clear
112
+
113
+ See {DRbQS::ProcessDefinition::Register#default\_clear}
114
+
115
+ ### usage
116
+
117
+ We can set help messages for "drbqs-execute --help <some_file>".
118
+
119
+ See {DRbQS::ProcessDefinition::Register#usage}