bud 0.1.0.pre1 → 0.9.0
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +23 -0
- data/{README → README.md} +6 -2
- data/docs/cheat.md +1 -8
- data/docs/intro.md +1 -1
- data/lib/bud/aggs.rb +16 -16
- data/lib/bud/bud_meta.rb +8 -15
- data/lib/bud/collections.rb +85 -172
- data/lib/bud/errors.rb +5 -1
- data/lib/bud/executor/elements.rb +133 -118
- data/lib/bud/executor/group.rb +6 -6
- data/lib/bud/executor/join.rb +25 -22
- data/lib/bud/metrics.rb +1 -1
- data/lib/bud/monkeypatch.rb +18 -29
- data/lib/bud/rebl.rb +5 -4
- data/lib/bud/rewrite.rb +21 -160
- data/lib/bud/source.rb +5 -5
- data/lib/bud/state.rb +13 -12
- data/lib/bud/storage/dbm.rb +13 -23
- data/lib/bud/storage/zookeeper.rb +0 -4
- data/lib/bud.rb +184 -162
- metadata +144 -216
- data/docs/deploy.md +0 -96
- data/lib/bud/deploy/countatomicdelivery.rb +0 -38
- data/lib/bud/joins.rb +0 -526
metadata
CHANGED
@@ -1,17 +1,10 @@
|
|
1
|
-
--- !ruby/object:Gem::Specification
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
2
|
name: bud
|
3
|
-
version: !ruby/object:Gem::Version
|
4
|
-
|
5
|
-
prerelease:
|
6
|
-
segments:
|
7
|
-
- 0
|
8
|
-
- 1
|
9
|
-
- 0
|
10
|
-
- pre
|
11
|
-
- 1
|
12
|
-
version: 0.1.0.pre1
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.9.0
|
5
|
+
prerelease:
|
13
6
|
platform: ruby
|
14
|
-
authors:
|
7
|
+
authors:
|
15
8
|
- Peter Alvaro
|
16
9
|
- Neil Conway
|
17
10
|
- Joseph M. Hellerstein
|
@@ -20,234 +13,184 @@ authors:
|
|
20
13
|
autorequire:
|
21
14
|
bindir: bin
|
22
15
|
cert_chain: []
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
- !ruby/object:Gem::Dependency
|
16
|
+
date: 2012-03-22 00:00:00.000000000 Z
|
17
|
+
dependencies:
|
18
|
+
- !ruby/object:Gem::Dependency
|
27
19
|
name: eventmachine
|
28
|
-
|
29
|
-
requirement: &id001 !ruby/object:Gem::Requirement
|
20
|
+
requirement: &70208102945340 !ruby/object:Gem::Requirement
|
30
21
|
none: false
|
31
|
-
requirements:
|
32
|
-
- -
|
33
|
-
- !ruby/object:Gem::Version
|
34
|
-
|
35
|
-
segments:
|
36
|
-
- 0
|
37
|
-
version: "0"
|
22
|
+
requirements:
|
23
|
+
- - ! '>='
|
24
|
+
- !ruby/object:Gem::Version
|
25
|
+
version: '0'
|
38
26
|
type: :runtime
|
39
|
-
version_requirements: *id001
|
40
|
-
- !ruby/object:Gem::Dependency
|
41
|
-
name: fastercsv
|
42
27
|
prerelease: false
|
43
|
-
|
28
|
+
version_requirements: *70208102945340
|
29
|
+
- !ruby/object:Gem::Dependency
|
30
|
+
name: fastercsv
|
31
|
+
requirement: &70208102944840 !ruby/object:Gem::Requirement
|
44
32
|
none: false
|
45
|
-
requirements:
|
46
|
-
- -
|
47
|
-
- !ruby/object:Gem::Version
|
48
|
-
|
49
|
-
segments:
|
50
|
-
- 0
|
51
|
-
version: "0"
|
33
|
+
requirements:
|
34
|
+
- - ! '>='
|
35
|
+
- !ruby/object:Gem::Version
|
36
|
+
version: '0'
|
52
37
|
type: :runtime
|
53
|
-
version_requirements: *id002
|
54
|
-
- !ruby/object:Gem::Dependency
|
55
|
-
name: gchart
|
56
38
|
prerelease: false
|
57
|
-
|
39
|
+
version_requirements: *70208102944840
|
40
|
+
- !ruby/object:Gem::Dependency
|
41
|
+
name: gchart
|
42
|
+
requirement: &70208102944420 !ruby/object:Gem::Requirement
|
58
43
|
none: false
|
59
|
-
requirements:
|
60
|
-
- -
|
61
|
-
- !ruby/object:Gem::Version
|
62
|
-
|
63
|
-
segments:
|
64
|
-
- 0
|
65
|
-
version: "0"
|
44
|
+
requirements:
|
45
|
+
- - ! '>='
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
66
48
|
type: :runtime
|
67
|
-
version_requirements: *id003
|
68
|
-
- !ruby/object:Gem::Dependency
|
69
|
-
name: getopt
|
70
49
|
prerelease: false
|
71
|
-
|
50
|
+
version_requirements: *70208102944420
|
51
|
+
- !ruby/object:Gem::Dependency
|
52
|
+
name: getopt
|
53
|
+
requirement: &70208102944000 !ruby/object:Gem::Requirement
|
72
54
|
none: false
|
73
|
-
requirements:
|
74
|
-
- -
|
75
|
-
- !ruby/object:Gem::Version
|
76
|
-
|
77
|
-
segments:
|
78
|
-
- 0
|
79
|
-
version: "0"
|
55
|
+
requirements:
|
56
|
+
- - ! '>='
|
57
|
+
- !ruby/object:Gem::Version
|
58
|
+
version: '0'
|
80
59
|
type: :runtime
|
81
|
-
version_requirements: *id004
|
82
|
-
- !ruby/object:Gem::Dependency
|
83
|
-
name: i18n
|
84
60
|
prerelease: false
|
85
|
-
|
61
|
+
version_requirements: *70208102944000
|
62
|
+
- !ruby/object:Gem::Dependency
|
63
|
+
name: i18n
|
64
|
+
requirement: &70208102943580 !ruby/object:Gem::Requirement
|
86
65
|
none: false
|
87
|
-
requirements:
|
88
|
-
- -
|
89
|
-
- !ruby/object:Gem::Version
|
90
|
-
|
91
|
-
segments:
|
92
|
-
- 0
|
93
|
-
version: "0"
|
66
|
+
requirements:
|
67
|
+
- - ! '>='
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: '0'
|
94
70
|
type: :runtime
|
95
|
-
version_requirements: *id005
|
96
|
-
- !ruby/object:Gem::Dependency
|
97
|
-
name: json
|
98
71
|
prerelease: false
|
99
|
-
|
72
|
+
version_requirements: *70208102943580
|
73
|
+
- !ruby/object:Gem::Dependency
|
74
|
+
name: json
|
75
|
+
requirement: &70208102943100 !ruby/object:Gem::Requirement
|
100
76
|
none: false
|
101
|
-
requirements:
|
102
|
-
- -
|
103
|
-
- !ruby/object:Gem::Version
|
104
|
-
|
105
|
-
segments:
|
106
|
-
- 0
|
107
|
-
version: "0"
|
77
|
+
requirements:
|
78
|
+
- - ! '>='
|
79
|
+
- !ruby/object:Gem::Version
|
80
|
+
version: '0'
|
108
81
|
type: :runtime
|
109
|
-
version_requirements: *id006
|
110
|
-
- !ruby/object:Gem::Dependency
|
111
|
-
name: minitest
|
112
82
|
prerelease: false
|
113
|
-
|
114
|
-
|
115
|
-
requirements:
|
116
|
-
- - ">="
|
117
|
-
- !ruby/object:Gem::Version
|
118
|
-
hash: 3
|
119
|
-
segments:
|
120
|
-
- 0
|
121
|
-
version: "0"
|
122
|
-
type: :runtime
|
123
|
-
version_requirements: *id007
|
124
|
-
- !ruby/object:Gem::Dependency
|
83
|
+
version_requirements: *70208102943100
|
84
|
+
- !ruby/object:Gem::Dependency
|
125
85
|
name: msgpack
|
126
|
-
|
127
|
-
requirement: &id008 !ruby/object:Gem::Requirement
|
86
|
+
requirement: &70208102942640 !ruby/object:Gem::Requirement
|
128
87
|
none: false
|
129
|
-
requirements:
|
130
|
-
- -
|
131
|
-
- !ruby/object:Gem::Version
|
132
|
-
|
133
|
-
segments:
|
134
|
-
- 0
|
135
|
-
version: "0"
|
88
|
+
requirements:
|
89
|
+
- - ! '>='
|
90
|
+
- !ruby/object:Gem::Version
|
91
|
+
version: '0'
|
136
92
|
type: :runtime
|
137
|
-
version_requirements: *id008
|
138
|
-
- !ruby/object:Gem::Dependency
|
139
|
-
name: nestful
|
140
93
|
prerelease: false
|
141
|
-
|
94
|
+
version_requirements: *70208102942640
|
95
|
+
- !ruby/object:Gem::Dependency
|
96
|
+
name: nestful
|
97
|
+
requirement: &70208102942180 !ruby/object:Gem::Requirement
|
142
98
|
none: false
|
143
|
-
requirements:
|
144
|
-
- -
|
145
|
-
- !ruby/object:Gem::Version
|
146
|
-
|
147
|
-
segments:
|
148
|
-
- 0
|
149
|
-
version: "0"
|
99
|
+
requirements:
|
100
|
+
- - ! '>='
|
101
|
+
- !ruby/object:Gem::Version
|
102
|
+
version: '0'
|
150
103
|
type: :runtime
|
151
|
-
version_requirements: *id009
|
152
|
-
- !ruby/object:Gem::Dependency
|
153
|
-
name: ruby-graphviz
|
154
104
|
prerelease: false
|
155
|
-
|
105
|
+
version_requirements: *70208102942180
|
106
|
+
- !ruby/object:Gem::Dependency
|
107
|
+
name: ruby-graphviz
|
108
|
+
requirement: &70208102941740 !ruby/object:Gem::Requirement
|
156
109
|
none: false
|
157
|
-
requirements:
|
158
|
-
- -
|
159
|
-
- !ruby/object:Gem::Version
|
160
|
-
|
161
|
-
segments:
|
162
|
-
- 0
|
163
|
-
version: "0"
|
110
|
+
requirements:
|
111
|
+
- - ! '>='
|
112
|
+
- !ruby/object:Gem::Version
|
113
|
+
version: '0'
|
164
114
|
type: :runtime
|
165
|
-
version_requirements: *id010
|
166
|
-
- !ruby/object:Gem::Dependency
|
167
|
-
name: ruby2ruby
|
168
115
|
prerelease: false
|
169
|
-
|
116
|
+
version_requirements: *70208102941740
|
117
|
+
- !ruby/object:Gem::Dependency
|
118
|
+
name: ruby2ruby
|
119
|
+
requirement: &70208102941180 !ruby/object:Gem::Requirement
|
170
120
|
none: false
|
171
|
-
requirements:
|
121
|
+
requirements:
|
172
122
|
- - <
|
173
|
-
- !ruby/object:Gem::Version
|
174
|
-
hash: 25
|
175
|
-
segments:
|
176
|
-
- 1
|
177
|
-
- 3
|
178
|
-
- 1
|
123
|
+
- !ruby/object:Gem::Version
|
179
124
|
version: 1.3.1
|
180
125
|
type: :runtime
|
181
|
-
version_requirements: *id011
|
182
|
-
- !ruby/object:Gem::Dependency
|
183
|
-
name: ruby_parser
|
184
126
|
prerelease: false
|
185
|
-
|
127
|
+
version_requirements: *70208102941180
|
128
|
+
- !ruby/object:Gem::Dependency
|
129
|
+
name: ruby_parser
|
130
|
+
requirement: &70208102940620 !ruby/object:Gem::Requirement
|
186
131
|
none: false
|
187
|
-
requirements:
|
188
|
-
- -
|
189
|
-
- !ruby/object:Gem::Version
|
190
|
-
|
191
|
-
segments:
|
192
|
-
- 0
|
193
|
-
version: "0"
|
132
|
+
requirements:
|
133
|
+
- - ! '>='
|
134
|
+
- !ruby/object:Gem::Version
|
135
|
+
version: '0'
|
194
136
|
type: :runtime
|
195
|
-
version_requirements: *id012
|
196
|
-
- !ruby/object:Gem::Dependency
|
197
|
-
name: superators19
|
198
137
|
prerelease: false
|
199
|
-
|
138
|
+
version_requirements: *70208102940620
|
139
|
+
- !ruby/object:Gem::Dependency
|
140
|
+
name: superators19
|
141
|
+
requirement: &70208102939800 !ruby/object:Gem::Requirement
|
200
142
|
none: false
|
201
|
-
requirements:
|
202
|
-
- -
|
203
|
-
- !ruby/object:Gem::Version
|
204
|
-
|
205
|
-
segments:
|
206
|
-
- 0
|
207
|
-
version: "0"
|
143
|
+
requirements:
|
144
|
+
- - ! '>='
|
145
|
+
- !ruby/object:Gem::Version
|
146
|
+
version: '0'
|
208
147
|
type: :runtime
|
209
|
-
version_requirements: *id013
|
210
|
-
- !ruby/object:Gem::Dependency
|
211
|
-
name: syntax
|
212
148
|
prerelease: false
|
213
|
-
|
149
|
+
version_requirements: *70208102939800
|
150
|
+
- !ruby/object:Gem::Dependency
|
151
|
+
name: syntax
|
152
|
+
requirement: &70208102938500 !ruby/object:Gem::Requirement
|
214
153
|
none: false
|
215
|
-
requirements:
|
216
|
-
- -
|
217
|
-
- !ruby/object:Gem::Version
|
218
|
-
|
219
|
-
segments:
|
220
|
-
- 0
|
221
|
-
version: "0"
|
154
|
+
requirements:
|
155
|
+
- - ! '>='
|
156
|
+
- !ruby/object:Gem::Version
|
157
|
+
version: '0'
|
222
158
|
type: :runtime
|
223
|
-
version_requirements: *id014
|
224
|
-
- !ruby/object:Gem::Dependency
|
225
|
-
name: uuid
|
226
159
|
prerelease: false
|
227
|
-
|
160
|
+
version_requirements: *70208102938500
|
161
|
+
- !ruby/object:Gem::Dependency
|
162
|
+
name: uuid
|
163
|
+
requirement: &70208102937500 !ruby/object:Gem::Requirement
|
228
164
|
none: false
|
229
|
-
requirements:
|
230
|
-
- -
|
231
|
-
- !ruby/object:Gem::Version
|
232
|
-
|
233
|
-
segments:
|
234
|
-
- 0
|
235
|
-
version: "0"
|
165
|
+
requirements:
|
166
|
+
- - ! '>='
|
167
|
+
- !ruby/object:Gem::Version
|
168
|
+
version: '0'
|
236
169
|
type: :runtime
|
237
|
-
|
238
|
-
|
239
|
-
|
170
|
+
prerelease: false
|
171
|
+
version_requirements: *70208102937500
|
172
|
+
- !ruby/object:Gem::Dependency
|
173
|
+
name: minitest
|
174
|
+
requirement: &70208102937020 !ruby/object:Gem::Requirement
|
175
|
+
none: false
|
176
|
+
requirements:
|
177
|
+
- - ! '>='
|
178
|
+
- !ruby/object:Gem::Version
|
179
|
+
version: '0'
|
180
|
+
type: :development
|
181
|
+
prerelease: false
|
182
|
+
version_requirements: *70208102937020
|
183
|
+
description: A prototype of the Bloom distributed programming language as a Ruby DSL.
|
184
|
+
email:
|
240
185
|
- bloomdevs@gmail.com
|
241
|
-
executables:
|
186
|
+
executables:
|
242
187
|
- rebl
|
243
188
|
- budplot
|
244
189
|
- budvis
|
245
190
|
- budtimelines
|
246
191
|
extensions: []
|
247
|
-
|
248
192
|
extra_rdoc_files: []
|
249
|
-
|
250
|
-
files:
|
193
|
+
files:
|
251
194
|
- lib/bud/aggs.rb
|
252
195
|
- lib/bud/bud_meta.rb
|
253
196
|
- lib/bud/bust/bust.rb
|
@@ -255,13 +198,11 @@ files:
|
|
255
198
|
- lib/bud/bust/client/restclient.rb
|
256
199
|
- lib/bud/collections.rb
|
257
200
|
- lib/bud/depanalysis.rb
|
258
|
-
- lib/bud/deploy/countatomicdelivery.rb
|
259
201
|
- lib/bud/errors.rb
|
260
202
|
- lib/bud/executor/elements.rb
|
261
203
|
- lib/bud/executor/group.rb
|
262
204
|
- lib/bud/executor/join.rb
|
263
205
|
- lib/bud/graphs.rb
|
264
|
-
- lib/bud/joins.rb
|
265
206
|
- lib/bud/meta_algebra.rb
|
266
207
|
- lib/bud/metrics.rb
|
267
208
|
- lib/bud/monkeypatch.rb
|
@@ -285,7 +226,6 @@ files:
|
|
285
226
|
- docs/bloom-loop.png
|
286
227
|
- docs/bust.md
|
287
228
|
- docs/cheat.md
|
288
|
-
- docs/deploy.md
|
289
229
|
- docs/getstarted.md
|
290
230
|
- docs/intro.md
|
291
231
|
- docs/modules.md
|
@@ -305,44 +245,32 @@ files:
|
|
305
245
|
- examples/chat/chat_server.rb
|
306
246
|
- examples/chat/README.md
|
307
247
|
- examples/README
|
308
|
-
- README
|
248
|
+
- README.md
|
309
249
|
- LICENSE
|
250
|
+
- History.txt
|
310
251
|
homepage: http://www.bloom-lang.org
|
311
|
-
licenses:
|
252
|
+
licenses:
|
312
253
|
- BSD
|
313
254
|
post_install_message:
|
314
255
|
rdoc_options: []
|
315
|
-
|
316
|
-
require_paths:
|
256
|
+
require_paths:
|
317
257
|
- lib
|
318
|
-
required_ruby_version: !ruby/object:Gem::Requirement
|
258
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
319
259
|
none: false
|
320
|
-
requirements:
|
321
|
-
- -
|
322
|
-
- !ruby/object:Gem::Version
|
323
|
-
hash: 57
|
324
|
-
segments:
|
325
|
-
- 1
|
326
|
-
- 8
|
327
|
-
- 7
|
260
|
+
requirements:
|
261
|
+
- - ! '>='
|
262
|
+
- !ruby/object:Gem::Version
|
328
263
|
version: 1.8.7
|
329
|
-
required_rubygems_version: !ruby/object:Gem::Requirement
|
264
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
330
265
|
none: false
|
331
|
-
requirements:
|
332
|
-
- -
|
333
|
-
- !ruby/object:Gem::Version
|
334
|
-
|
335
|
-
segments:
|
336
|
-
- 1
|
337
|
-
- 3
|
338
|
-
- 1
|
339
|
-
version: 1.3.1
|
266
|
+
requirements:
|
267
|
+
- - ! '>='
|
268
|
+
- !ruby/object:Gem::Version
|
269
|
+
version: '0'
|
340
270
|
requirements: []
|
341
|
-
|
342
271
|
rubyforge_project: bloom-lang
|
343
272
|
rubygems_version: 1.8.17
|
344
273
|
signing_key:
|
345
274
|
specification_version: 3
|
346
275
|
summary: A prototype Bloom DSL for distributed programming.
|
347
276
|
test_files: []
|
348
|
-
|
data/docs/deploy.md
DELETED
@@ -1,96 +0,0 @@
|
|
1
|
-
# Deployment
|
2
|
-
|
3
|
-
Bud provides support for deploying a program onto a set of Bud instances. At the moment, two types of deployments are supported: fork-based local deployment and EC2 deployment. Intuitively, you include the module corresponding to the type of deployment you want into a Bud class, which you instantiate and run on a node called the "deployer." The deployer then spins up a requested number of Bud instances and distributes initial data.
|
4
|
-
|
5
|
-
First, decide which type of deployment you want to use.
|
6
|
-
|
7
|
-
## Fork-based Local Deployment
|
8
|
-
|
9
|
-
To use fork-based deployment, you'll need to include it in your class:
|
10
|
-
|
11
|
-
include ForkDeploy
|
12
|
-
|
13
|
-
The next step is to declare how many nodes you want to the program to be spun up on. You need to do this in a `deploystrap` block. A `deploystrap` block is run before `bootstrap`, and is only run for a Bud class that is instantiated with the option `:deploy => true`. As an example:
|
14
|
-
|
15
|
-
deploystrap do
|
16
|
-
num_nodes <= [[2]]
|
17
|
-
end
|
18
|
-
|
19
|
-
Fork-based deployment will spin up `num_nodes` local processes, each containing one Bud instance, running the class that you include `ForkDeploy` in. The deployment code will populate a binary collection called `node`; the first columm is a "node ID" -- a distinct integer from the range `[0, num_nodes - 1]` -- and the second argument is an "IP:port" string associated with the node. Nodes are spun up on ephemeral ports, listening on "localhost".
|
20
|
-
|
21
|
-
Now, you need to define how you want the initial data to be distributed. You can do this, for example, by writing (multiple) rules with `initial_data` in the head. These rules can appear in any `bloom` block in your program. The schema of `initial_data` is as follows: [node ID, relation name as a symbol, list of tuples].
|
22
|
-
|
23
|
-
For example, to distribute the IP address and port of the "deployer" to all of the other nodes in a relation called `master`, you might decide to write something like this:
|
24
|
-
|
25
|
-
initial_data <= node {|n| [n.uid, :master, [[ip_port]]]}
|
26
|
-
|
27
|
-
Note that the relation (`master` in this case) cannot be a channel -- you may only distribute data to scratches and tables. Initial data is transferred only after _all_ nodes are spun up; this ensures that initial data will never be lost because a node is not yet listening on a socket, for example. Initial data is transmitted atomically to each node; this means that on each node, _all_ initial data in _all_ relations will arrive at the same Bud timestep. However, there is no global barrier for transfer of initial data. For example, if initial data is distributed to nodes 1 and 2, node 1 may receive its initial data first, and then send subsequent messages on channels to node 2 which node 2 may receive before its initial data.
|
28
|
-
|
29
|
-
The final step is to add `:deploy => true` to the instantiation of your class. Note that the fork-based deployer will spin up nodes without `:deploy => true`, so you don't forkbomb your system.
|
30
|
-
|
31
|
-
|
32
|
-
## EC2 Deployment
|
33
|
-
|
34
|
-
To use EC2 deployment, you'll need to require it in your program:
|
35
|
-
|
36
|
-
require 'bud/deploy/ec2deploy'
|
37
|
-
|
38
|
-
Note that the `amazon-ec2`, `net-scp`, and `net-ssh` gems must be installed.
|
39
|
-
|
40
|
-
Next, include the `EC2Deploy` module in your class:
|
41
|
-
|
42
|
-
include EC2Deploy
|
43
|
-
|
44
|
-
As in local deployment, you'll need to define `num_nodes` in a `deploystrap` block. Additionally in the `deploystrap` block, you need to define the following relations: `ruby_command`, `init_dir`, `access_key_id`, `secret_access_key`, `key_name`, `ec2_key_location`. `ruby_command` is the command line to run on the EC2 nodes. For example, if you want to run a file called `test.rb` on your EC2 nodes, you'd put:
|
45
|
-
|
46
|
-
ruby_command <= [["ruby test.rb"]]
|
47
|
-
|
48
|
-
Note that whatever file you specify here _must_ take three arguments. Here's the recommended boilerplate that you use for the file you want to deploy, assuming `Test` is the name of your class:
|
49
|
-
|
50
|
-
ip, port = ARGV[0].split(':')
|
51
|
-
ext_ip, ext_port = ARGV[1].split(':')
|
52
|
-
Test.new(:ip => ip,
|
53
|
-
:ext_ip => ext_ip,
|
54
|
-
:port => port,
|
55
|
-
:deploy => not ARGV[2]).run_fg
|
56
|
-
|
57
|
-
`init_dir` is the directory that contains all of the Ruby files you want to deploy. Alternatively, `init_dir` may be the single filename you include in your `ruby_command`. If it is a directory, it must contain the file you execute in your `ruby_command`. Unless you're doing something particularly fancy, you'll usually set `init_dir` to ".":
|
58
|
-
|
59
|
-
init_dir <= [["."]]
|
60
|
-
|
61
|
-
This recursively copies all directories and files rooted at the current working directory. `access_key_id` is your EC2 access key ID, and `secret_access_key` is your EC2 secret access key.
|
62
|
-
|
63
|
-
access_key_id <= [["XXXXXXXXXXXXXXXXXXXX"]]
|
64
|
-
secret_access_key <= [["XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"]]
|
65
|
-
|
66
|
-
`key_name` is the name of the keypair you want to use to SSH in to the EC2 instances. For example, if you have a keypair named "bob", you'd write:
|
67
|
-
|
68
|
-
key_name <= [["bob"]]
|
69
|
-
|
70
|
-
Finally, `ec2_key_location` is the path to the private key of the `key_name` keypair. For example:
|
71
|
-
|
72
|
-
ec2_key_location <= [["/home/bob/.ssh/bob.pem"]]
|
73
|
-
|
74
|
-
EC2 deployment will spin up `num_nodes` instances (using defaults) on EC2 using a pre-rolled Bud AMI based on Amazon's 32-bit Linux AMI (`ami-8c1fece5`). Each instance contains one Bud instance, which runs the `ruby_command`. Like before, the deployment code will populate a binary relation called `node`; the first attribute is a "node ID" -- a distinct integer from the range [0, num_nodes - 1] -- and the second attribute is an "IP:port" string associated with the node. Nodes are currently spun up on fixed port 54321.
|
75
|
-
|
76
|
-
Defining `initial_data` works exactly the same way with EC2 deployment as it does with local deployment.
|
77
|
-
|
78
|
-
There is a slight catch with EC2 deployment. Sometimes EC2 tells us that the nodes have all started up, but really, one or more nodes will never start up. Currently, in this scenario, deployment exceeds the maximum number of SSH retries, and throws an exception.
|
79
|
-
|
80
|
-
Note that EC2 deployment does *not* shut down the EC2 nodes it starts up under any circumstances. This means you must use some alternate means to shut down the nodes, such as logging onto the EC2 web interface and terminating the nodes.
|
81
|
-
|
82
|
-
## Examples
|
83
|
-
|
84
|
-
Check out the `examples/deploy` directory in Bud. There is a simple token ring example that establishes a ring involving 10 nodes and sends a token around the ring continuously. This example can be deployed locally using the fork-based deployer:
|
85
|
-
|
86
|
-
ruby tokenring-fork.rb
|
87
|
-
|
88
|
-
or on EC2:
|
89
|
-
|
90
|
-
ruby tokenring-ec2.rb local_ip:local_port ext_ip:ext_port true
|
91
|
-
|
92
|
-
"ext_ip" and "ext_port" should be set to the externally-visible IP and port of the computer you are deploying from. For example, if you are behind a home router, you will want to set "ext_ip" to your public IP address, and ensure that your router forwards "ext_port" to local_port on the computer with private IP "local_ip".
|
93
|
-
|
94
|
-
Note that before running `tokenring-ec2`, you must create a file named "keys.rb" that contains definitions for `access_key_id`, `secret_access_key`, `key_name` and `ec2_key_location`.
|
95
|
-
|
96
|
-
Output will be displayed to show the progress of the deployment. Be patient, it may take a while for output to appear. Once deployment is complete and all nodes are ready, each node will display output indicating when it has the token. All output will be visible for the fork-based deployment case, whereas only the deployer node's output will be visible for the EC2 deployment case (stdout of all other nodes is written to local disk).
|
@@ -1,38 +0,0 @@
|
|
1
|
-
require 'rubygems'
|
2
|
-
require 'bud'
|
3
|
-
|
4
|
-
# XXX: delivery modules are a massive hack. we need to think about
|
5
|
-
# aspect-oriented programming here, or allow users to extend the definitions of
|
6
|
-
# existing table types
|
7
|
-
module CountAtomicDelivery # :nodoc: all
|
8
|
-
state do
|
9
|
-
scratch :atomic_data_in, [:loc, :tuple]
|
10
|
-
channel :atomic_data_chan, [:@loc, :tuple]
|
11
|
-
table :atomic_data_recv, [:loc, :tuple]
|
12
|
-
|
13
|
-
channel :atomic_count_chan,[:@loc, :cnt]
|
14
|
-
table :atomic_count_recv, [] => [:cnt]
|
15
|
-
|
16
|
-
scratch :atomic_recv_count, [:loc] => [:cnt]
|
17
|
-
scratch :atomic_data, [:loc, :tuple]
|
18
|
-
scratch :atomic_data_out, [:tuple]
|
19
|
-
end
|
20
|
-
|
21
|
-
bloom :countatomicdelivery do
|
22
|
-
temp :atomic_count <= atomic_data_in.group([:loc], count)
|
23
|
-
|
24
|
-
atomic_data_chan <~ atomic_data_in
|
25
|
-
atomic_count_chan <~ atomic_count
|
26
|
-
|
27
|
-
atomic_count_recv <= atomic_count_chan {|c| [c.cnt]}
|
28
|
-
atomic_data_recv <= atomic_data_chan
|
29
|
-
|
30
|
-
atomic_recv_count <= atomic_data_recv.group([:loc], count)
|
31
|
-
|
32
|
-
atomic_data <= (atomic_recv_count * atomic_count_recv * atomic_data_recv).combos(atomic_recv_count.cnt => atomic_count_recv.cnt) {|rc, cr, d| d}
|
33
|
-
|
34
|
-
atomic_data_recv <- atomic_data
|
35
|
-
|
36
|
-
atomic_data_out <= atomic_data {|a| [a.tuple]}
|
37
|
-
end
|
38
|
-
end
|