zillabyte 0.0.6

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,369 @@
1
+ require "rubygems"
2
+ require "json"
3
+
4
+ module Zillabyte
5
+
6
+ module Storm
7
+
8
+ module Protocol
9
+
10
+ class << self
11
+ attr_accessor :mode, :pending_commands, :pipe_name, :pipe_to_java, :pipe_from_java
12
+ end
13
+
14
+ self.pending_commands = []
15
+
16
+ def setup_pipes
17
+ pipe_name = Storm::Protocol.pipe_name
18
+ if(pipe_name and File.exist?(pipe_name+".in"))
19
+ Storm::Protocol.pipe_to_java = File.open("#{pipe_name}.in","w+")
20
+ else
21
+ Storm::Protocol.pipe_to_java = $stdout
22
+ end
23
+
24
+ if(pipe_name and File.exist?(pipe_name+".out"))
25
+ Storm::Protocol.pipe_from_java = File.open("#{pipe_name}.out","r+")
26
+ else
27
+ Storm::Protocol.pipe_from_java = $stdin
28
+ end
29
+ end
30
+
31
+ def read_message
32
+ msg = ""
33
+ loop do
34
+ line = Storm::Protocol.pipe_from_java.readline.chomp#STDIN.readline.chomp
35
+ break if line == "end"
36
+ msg << line
37
+ msg << "\n"
38
+ end
39
+
40
+ encoding_options = {
41
+ :invalid => :replace, # Replace invalid byte sequences
42
+ :undef => :replace, # Replace anything not defined in ASCII
43
+ :replace => '' # Use a blank for those replacements
44
+ }
45
+ msg.encode! Encoding.find('ASCII'), encoding_options
46
+
47
+ JSON.parse msg.chomp
48
+ end
49
+
50
+ def read_command
51
+ Storm::Protocol.pending_commands.shift ||
52
+ begin
53
+ msg = read_message
54
+ while msg.is_a? Array
55
+ Storm::Protocol.pending_taskids.push(msg)
56
+ msg = read_message
57
+ end
58
+ msg
59
+ rescue JSON::ParserError => e
60
+ fail "error: #{e}"
61
+ {}
62
+ end
63
+ end
64
+
65
+ def send_msg_to_parent(msg)
66
+ # log msg
67
+ # log msg.to_json
68
+ Storm::Protocol.pipe_to_java.write(msg.to_json+"\n")
69
+ Storm::Protocol.pipe_to_java.write("end\n")
70
+ Storm::Protocol.pipe_to_java.flush
71
+ end
72
+
73
+ def send_pid(heartbeat_dir)
74
+ pid = Process.pid
75
+ send_msg_to_parent({'pid' => pid})
76
+ File.open("#{heartbeat_dir}/#{pid}", "w").close
77
+ end
78
+
79
+ def emit(*args)
80
+
81
+ stream = nil
82
+ tuple = nil
83
+ meta = {}
84
+
85
+ if (args.size == 1)
86
+ tuple = args[0]
87
+ elsif(args.size == 2)
88
+ stream = args[0]
89
+ tuple = args[1]
90
+ else
91
+ stream = args[0]
92
+ tuple = args[1]
93
+ meta = args[2]
94
+ end
95
+
96
+ m = {:command => :emit, :tuple => tuple, :stream => stream, :meta => meta}
97
+ send_msg_to_parent m
98
+ end
99
+
100
+ def ack(tup)
101
+ send_msg_to_parent :command => :ack, :id => tup.id
102
+ end
103
+
104
+ def done()
105
+ send_msg_to_parent :command => :done #, :id => tup.id
106
+ # read_task_ids
107
+ end
108
+
109
+ def fail(msg)
110
+ send_msg_to_parent :command => :fail, :msg => msg.to_s
111
+ end
112
+
113
+ def log(msg)
114
+ send_msg_to_parent :command => :log, :msg => msg.to_s
115
+ end
116
+
117
+ def handshake
118
+ setup_info = read_message
119
+ send_pid setup_info['pidDir']
120
+ [setup_info['conf'], setup_info['context']]
121
+ end
122
+ end
123
+
124
+
125
+ class Spout
126
+ include Storm::Protocol
127
+
128
+ def open(conf, context); end
129
+
130
+ def next_batch; end
131
+
132
+ def ack(id); end
133
+
134
+ def run(pipe_name)
135
+ Storm::Protocol.mode = 'spout'
136
+ Storm::Protocol.pipe_name = pipe_name
137
+ setup_pipes
138
+ open(*handshake)
139
+
140
+ begin
141
+ while true
142
+ msg = read_command
143
+ case msg['command']
144
+ when 'next'
145
+ next_batch
146
+ done
147
+ when 'ack'
148
+ ack(msg['id'])
149
+ when 'fail'
150
+ fail(msg['id'])
151
+ end
152
+ end
153
+ rescue Exception => e
154
+ fail 'Exception in spout: ' + e.message + ' - ' + e.backtrace.join('\n')
155
+ end
156
+ end
157
+ end
158
+
159
+ class Each
160
+ include Storm::Protocol
161
+
162
+ def prepare(conf, context); end
163
+
164
+ def execute(tuple); end
165
+
166
+ def run(pipe_name)
167
+ Storm::Protocol.mode = 'each'
168
+ Storm::Protocol.pipe_name = pipe_name
169
+ setup_pipes
170
+ prepare(*handshake)
171
+
172
+ begin
173
+ while true
174
+ t = nil
175
+ begin
176
+ t = Tuple.from_hash(read_command)
177
+ if(!t)
178
+ next
179
+ end
180
+ execute t
181
+ rescue Exception => e
182
+ fail 'Exception in bolt (A): ' + e.message + ' - ' + e.backtrace.join('\n')
183
+ ensure
184
+ done()
185
+ end
186
+ end
187
+ rescue Exception => e
188
+ fail 'Exception in bolt (B): ' + e.message + ' - ' + e.backtrace.join('\n')
189
+ end
190
+ end
191
+ end
192
+
193
+ class AggregateStart
194
+ include Storm::Protocol
195
+
196
+ def start(tuple); end
197
+
198
+ def run(pipe_name)
199
+ Storm::Protocol.mode = 'agg_start'
200
+ Storm::Protocol.pipe_name = pipe_name
201
+ setup_pipes
202
+ handshake
203
+
204
+ begin
205
+ while true
206
+ t = nil
207
+ begin
208
+ t = Tuple.from_hash(read_command)
209
+ if(!t)
210
+ next
211
+ end
212
+ start t
213
+ rescue Exception => e
214
+ fail 'Exception in bolt (A): ' + e.message + ' - ' + e.backtrace.join('\n')
215
+ ensure
216
+ done()
217
+ end
218
+ end
219
+ rescue Exception => e
220
+ fail 'Exception in bolt (B): ' + e.message + ' - ' + e.backtrace.join('\n')
221
+ end
222
+ end
223
+ end
224
+
225
+ class AggregateAggregate
226
+ include Storm::Protocol
227
+
228
+ def aggregate(tuple1, tuple2); end
229
+
230
+ def run(pipe_name)
231
+ Storm::Protocol.mode = 'agg_aggregate'
232
+ Storm::Protocol.pipe_name = pipe_name
233
+ setup_pipes
234
+ handshake
235
+
236
+ begin
237
+ while true
238
+ t = nil
239
+ begin
240
+ t1 = Tuple.from_hash(read_command)
241
+ if(!t1)
242
+ next
243
+ end
244
+ t2 = Tuple.from_hash(read_command)
245
+ if(!t2)
246
+ next
247
+ end
248
+ aggregate t1, t2
249
+ rescue Exception => e
250
+ fail 'Exception in bolt (A): ' + e.message + ' - ' + e.backtrace.join('\n')
251
+ ensure
252
+ done()
253
+ end
254
+ end
255
+ rescue Exception => e
256
+ fail 'Exception in bolt (B): ' + e.message + ' - ' + e.backtrace.join('\n')
257
+ end
258
+ end
259
+ end
260
+
261
+ class AggregateComplete
262
+ include Storm::Protocol
263
+
264
+ def complete(tuple); end
265
+
266
+ def run(pipe_name)
267
+ Storm::Protocol.mode = 'agg_complete'
268
+ Storm::Protocol.pipe_name = pipe_name
269
+ setup_pipes
270
+ handshake
271
+
272
+ begin
273
+ while true
274
+ t = nil
275
+ begin
276
+ t = Tuple.from_hash(read_command)
277
+ if(!t)
278
+ next
279
+ end
280
+ complete t
281
+ rescue Exception => e
282
+ fail 'Exception in bolt (A): ' + e.message + ' - ' + e.backtrace.join('\n')
283
+ ensure
284
+ done()
285
+ end
286
+ end
287
+ rescue Exception => e
288
+ fail 'Exception in bolt (B): ' + e.message + ' - ' + e.backtrace.join('\n')
289
+ end
290
+ end
291
+ end
292
+ end
293
+
294
+ module Harness
295
+
296
+ class SpoutController < Storm::Spout
297
+
298
+ def initialize(harness, progress)
299
+ @harness = harness
300
+ @progress = progress
301
+ end
302
+
303
+ def open(*args)
304
+ @harness._prepare.call(self, *args) if @harness._prepare
305
+ end
306
+
307
+ def next_batch
308
+ @harness._next_batch.call(self)
309
+ end
310
+
311
+ end
312
+
313
+ class EachController < Storm::Each
314
+
315
+ def initialize(harness, progress)
316
+ @harness = harness
317
+ @progress = progress
318
+ end
319
+
320
+ def execute(*args)
321
+ @harness._execute.call(self, *args)
322
+ end
323
+
324
+ def prepare(*args)
325
+ @harness._prepare.call(self, *args) if @harness._prepare
326
+ end
327
+
328
+ end
329
+
330
+ class AggregateStartController < Storm::AggregateStart
331
+
332
+ def initialize(harness, progress)
333
+ @harness = harness
334
+ @progress = progress
335
+ end
336
+
337
+ def start(*args)
338
+ @harness._start.call(self, *args)
339
+ end
340
+
341
+ end
342
+
343
+ class AggregateAggregateController < Storm::AggregateAggregate
344
+
345
+ def initialize(harness, progress)
346
+ @harness = harness
347
+ @progress = progress
348
+ end
349
+
350
+ def aggregate(*args)
351
+ @harness._aggregate.call(self, *args)
352
+ end
353
+
354
+ end
355
+
356
+ class AggregateCompleteController < Storm::AggregateComplete
357
+
358
+ def initialize(harness, progress)
359
+ @harness = harness
360
+ @progress = progress
361
+ end
362
+
363
+ def complete(*args)
364
+ @harness._complete.call(self, *args)
365
+ end
366
+
367
+ end
368
+ end
369
+ end
@@ -0,0 +1,131 @@
1
+ require 'optparse'
2
+
3
+ class Zillabyte::Harness::SimpleFunction
4
+ attr_accessor :_nodes, :_relation, :_matches, :_emits, :_prepare, :_execute, :_name, :_info_file, :_options
5
+
6
+ def self.build()
7
+ h = Zillabyte::Harness::SimpleFunction.new()
8
+ yield(h)
9
+ h._name = h._name || Dir.pwd.split("/")[-1]
10
+ Zillabyte::Harness::Helper.check_name("simple_function", h._name, {})
11
+ Zillabyte::Harness::Helper.check_emits("simple_function", h._emits, {})
12
+ generic_emits = h.get_generic_emits
13
+
14
+ h._nodes = []
15
+ h._options = Zillabyte::Harness::Helper.opt_parser()
16
+
17
+ if(h._options[:command] == :info)
18
+ h._info_file = File.open(h._options[:file],"w+")
19
+ hash = {"language" => "ruby", "name" => h._name}
20
+ Zillabyte::Harness::Helper.write_hash_to_file(hash, h._info_file)
21
+ end
22
+
23
+ h.build_spout()
24
+ fn = h.build_each(generic_emits)
25
+ h.build_sink()
26
+
27
+ if(h._options[:command] == :execute and h._options[:name] == h._name)
28
+ pipe_name = h._options[:pipe]
29
+ c = Zillabyte::Harness::EachController.new(fn, progress = Zillabyte::Common::Progress.new)
30
+ c.run(pipe_name)
31
+ end
32
+
33
+ h
34
+ end
35
+
36
+ def name(v)
37
+ @_name = v
38
+ end
39
+
40
+ def matches(v, options = {})
41
+ case v
42
+ when String
43
+ @_relation = { :query => v, :options => options.is_a?(Hash) ? options : {} }
44
+ when Array
45
+ @_matches = v
46
+ end
47
+ end
48
+
49
+ def emits(v)
50
+ @_emits = v
51
+ end
52
+
53
+ def prepare(&block)
54
+ @_prepare = block
55
+ end
56
+
57
+ def execute(&block)
58
+ @_execute = block
59
+ end
60
+
61
+ def get_generic_emits()
62
+ generic_emits = []
63
+ @_emits.each do |relation|
64
+ temit = []
65
+ relation[1].each do |column|
66
+ column.each do |col, type|
67
+ temit << col
68
+ end
69
+ end
70
+ generic_emits << [relation[0], temit]
71
+ end
72
+ generic_emits
73
+ end
74
+
75
+ def build_spout()
76
+ h = Zillabyte::Harness::Spout.new(false)
77
+ h._matches = @_matches if @_matches
78
+ h._relation = @_relation if @_relation
79
+ @_nodes << h
80
+ if(@_options[:command] == :info)
81
+ info_hash = {"name" => h._name, "type" => h._type}
82
+ if(h._relation)
83
+ info_hash["relation"] = h._relation
84
+ elsif(h._matches)
85
+ info_hash["matches"] = h._matches
86
+ end
87
+ Zillabyte::Harness::Helper.write_hash_to_file(info_hash, @_info_file)
88
+ end
89
+ end
90
+
91
+ def build_each(generic_emits)
92
+ h = Zillabyte::Harness::Each.new()
93
+ h._name = @_name
94
+ h._emits = generic_emits
95
+ h._prepare = @_prepare
96
+ h._execute = @_execute
97
+ @_nodes << h
98
+ if(@_options[:command] == :info)
99
+ info_hash = {"name" => h._name, "type" => h._type, "emits" => h._emits}
100
+ Zillabyte::Harness::Helper.write_hash_to_file(info_hash, @_info_file)
101
+ end
102
+ h
103
+ end
104
+
105
+ def build_sink()
106
+ # Construct the sink...
107
+ n_sinks = @_emits.length
108
+ @_emits.each do |emit|
109
+ h = Zillabyte::Harness::Sink.new()
110
+ h._name = emit[0]
111
+ columns = emit[1]
112
+ columns.each do |col|
113
+ col.each do |cname, ctype|
114
+ h.column(cname, ctype)
115
+ end
116
+ end
117
+ if(n_sinks > 1)
118
+ h._consumes = h._name
119
+ end
120
+ @_nodes << h
121
+ if(@_options[:command] == :info)
122
+ info_hash = {"name" => h._name, "type" => h._type, "columns" => h._columns}
123
+ if(h._consumes)
124
+ info_hash["consumes"] = h._consumes
125
+ end
126
+ Zillabyte::Harness::Helper.write_hash_to_file(info_hash, @_info_file)
127
+ end
128
+ end
129
+ end
130
+
131
+ end