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
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}