zillabyte-cli 0.1.18 → 0.1.19
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +8 -8
- data/lib/zillabyte-cli/version.rb +1 -1
- data/lib/zillabyte/runner/app_runner.rb +123 -35
- data/lib/zillabyte/runner/component_operation.rb +77 -34
- data/lib/zillabyte/runner/component_runner.rb +119 -45
- data/lib/zillabyte/runner/multilang_operation.rb +459 -85
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
---
|
2
2
|
!binary "U0hBMQ==":
|
3
3
|
metadata.gz: !binary |-
|
4
|
-
|
4
|
+
OGE2NDJmZDQxOTAzNGE1YTYwYWE2MzZkNjFmODc5YmRhMDFlMTliZQ==
|
5
5
|
data.tar.gz: !binary |-
|
6
|
-
|
6
|
+
ZDc5YzRhNzYwMjRmNDE4OTc3NzI3ZWQxNWJmNDA0OWY0ZWI0NjY4Yg==
|
7
7
|
!binary "U0hBNTEy":
|
8
8
|
metadata.gz: !binary |-
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
NGI5MWJkNTkzZDY2ZjYxNGRkNThkNTM3YWExNzRhYmFhZTY2OTRlZjlhY2Yy
|
10
|
+
NzZkYTFiMzdkZDFhMmI3NWE4NjYwMWY3MjBhYzVkM2YzNThhMDE4Y2I5NWU0
|
11
|
+
ODI0MTZkN2E5MWRhMDQ1MWZmYTRiNzRkNTk3Yzc3MmZlOGNhZTI=
|
12
12
|
data.tar.gz: !binary |-
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
MTFiNzgxNTgwOWMyNzAzNWI1Zjg5YTQ1NWNiYTVlZDVmNDYzZDY3NTFmYTgx
|
14
|
+
ZjMyMDRiZTc4N2NlNTk1MDFjZGEzNmFkZWRmNjJlZjE3NTNhMDRhYTZmNGRm
|
15
|
+
ZjZjZmM1OTg3YzU1ZGU2MDZiZjg4YjE0NmU4Yjc2MDdiM2Q0ZTY=
|
@@ -22,10 +22,13 @@ class Zillabyte::Runner::AppRunner < Zillabyte::Command::Base
|
|
22
22
|
display "inferring your app details..."
|
23
23
|
describe_app(meta)
|
24
24
|
|
25
|
-
# Setup
|
25
|
+
# Setup nodes and arcs
|
26
26
|
@nodes = meta["nodes"]
|
27
|
+
@node_map = {}
|
28
|
+
@nodes.each do |n|
|
29
|
+
@node_map[n["name"]] = n
|
30
|
+
end
|
27
31
|
|
28
|
-
# Index stream consummers and emitters by stream name
|
29
32
|
@arcs = meta["arcs"]
|
30
33
|
|
31
34
|
# Organize component pipes
|
@@ -38,7 +41,6 @@ class Zillabyte::Runner::AppRunner < Zillabyte::Command::Base
|
|
38
41
|
display "starting cycle #{cycle}" unless cycles == 1
|
39
42
|
|
40
43
|
begin
|
41
|
-
|
42
44
|
# Setup component pipes
|
43
45
|
@nodes.each do |n|
|
44
46
|
|
@@ -50,15 +52,29 @@ class Zillabyte::Runner::AppRunner < Zillabyte::Command::Base
|
|
50
52
|
end
|
51
53
|
|
52
54
|
# Create two new pipes in the parent.
|
53
|
-
|
54
|
-
|
55
|
+
rd_child_1, wr_parent_1 = IO.pipe()
|
56
|
+
rd_parent_1, wr_child_1 = IO.pipe()
|
55
57
|
|
56
58
|
@operation_pipes[name] = {
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
59
|
+
"rd_child_1" => rd_child_1,
|
60
|
+
"wr_child_1" => wr_child_1,
|
61
|
+
"rd_parent_1" => rd_parent_1,
|
62
|
+
"wr_parent_1" => wr_parent_1
|
61
63
|
}
|
64
|
+
|
65
|
+
|
66
|
+
# Add a second(right hand side) set ofpipes for joins
|
67
|
+
if type == "join"
|
68
|
+
# Create two new pipes in the parent.
|
69
|
+
rd_child_2, wr_parent_2 = IO.pipe()
|
70
|
+
rd_parent_2, wr_child_2 = IO.pipe()
|
71
|
+
@operation_pipes[name]["rd_child_2"] = rd_child_2
|
72
|
+
@operation_pipes[name]["wr_child_2"] = wr_child_2
|
73
|
+
@operation_pipes[name]["rd_parent_2"] = rd_parent_2
|
74
|
+
@operation_pipes[name]["wr_parent_2"] = wr_parent_2
|
75
|
+
end
|
76
|
+
|
77
|
+
|
62
78
|
end
|
63
79
|
|
64
80
|
# Maps origin => {stream => [destinations]}
|
@@ -72,59 +88,124 @@ class Zillabyte::Runner::AppRunner < Zillabyte::Command::Base
|
|
72
88
|
@arc_map[origin][name] << a["dest"]
|
73
89
|
end
|
74
90
|
|
75
|
-
# Spawn component threads
|
91
|
+
# # Spawn component threads
|
76
92
|
@nodes.each do |n|
|
77
93
|
|
78
94
|
name = n["name"]
|
79
95
|
type = n["type"]
|
80
96
|
emits = n["emits"]
|
81
97
|
|
98
|
+
|
82
99
|
pipes = @operation_pipes[name]
|
83
|
-
rd_child = pipes[:rd_child]
|
84
|
-
wr_child = pipes[:wr_child]
|
85
|
-
rd_parent = pipes[:rd_parent]
|
86
|
-
wr_parent = pipes[:wr_parent]
|
87
100
|
|
88
101
|
# Fork.
|
89
102
|
pid = fork()
|
90
103
|
if pid # In parent
|
91
|
-
# Close the reading end of the child so we can write to the child.
|
92
|
-
|
93
|
-
# Close the writing end of the child so we can read from the child.
|
94
|
-
|
95
|
-
|
104
|
+
# Close the reading end of the first child so we can write to the child.
|
105
|
+
pipes["rd_child_1"].close()
|
106
|
+
# Close the writing end of the first child so we can read from the child.
|
107
|
+
pipes["wr_child_1"].close()
|
108
|
+
|
109
|
+
if type == "join"
|
110
|
+
# Close the reading end of the second child so we can write to the child.
|
111
|
+
pipes["rd_child_2"].close()
|
112
|
+
# Close the writing end of the second child so we can read from the child.
|
113
|
+
pipes["wr_child_2"].close()
|
114
|
+
end
|
96
115
|
else # in child
|
97
|
-
# Close the writing end of the parent so we can read from the parent.
|
98
|
-
|
99
|
-
# Close the reading end of the parent so we can write to the parent.
|
100
|
-
|
101
|
-
|
116
|
+
# Close the writing end of the first parent so we can read from the parent.
|
117
|
+
pipes["wr_parent_1"].close()
|
118
|
+
# Close the reading end of the first parent so we can write to the parent.
|
119
|
+
pipes["rd_parent_1"].close()
|
120
|
+
|
121
|
+
if type == "join"
|
122
|
+
# Close the reading end of the second child so we can write to the child.
|
123
|
+
pipes["rd_parent_2"].close()
|
124
|
+
# Close the writing end of the second child so we can read from the child.
|
125
|
+
pipes["wr_parent_2"].close()
|
126
|
+
end
|
102
127
|
|
103
128
|
|
129
|
+
begin
|
130
|
+
|
104
131
|
# Setup reading and writing pipes for communicating with consumee component
|
105
|
-
|
132
|
+
if type != "join"
|
133
|
+
in_pipes = {"rd_child_1" => @operation_pipes[name]["rd_child_1"], "wr_child_1" => @operation_pipes[name]["wr_child_1"]}
|
134
|
+
|
135
|
+
# Add join specific options
|
136
|
+
else
|
137
|
+
options[:join_options] = {}
|
138
|
+
in_pipes = {}
|
139
|
+
@arcs.each do |a|
|
140
|
+
|
141
|
+
if (a["dest"] == name)
|
142
|
+
# Left Side
|
143
|
+
if (a["left"] == 1)
|
144
|
+
options[:join_options][:lhs] = a["origin"]
|
145
|
+
in_pipes["rd_child_1"] = @operation_pipes[name]["rd_child_1"]
|
146
|
+
in_pipes["wr_child_1"] = @operation_pipes[name]["wr_child_1"]
|
147
|
+
# Right Side
|
148
|
+
elsif (a["right"] == 1)
|
149
|
+
options[:join_options][:rhs] = a["origin"]
|
150
|
+
in_pipes["rd_child_2"] = @operation_pipes[name]["rd_child_2"]
|
151
|
+
in_pipes["wr_child_2"] = @operation_pipes[name]["wr_child_2"]
|
152
|
+
end
|
153
|
+
end
|
154
|
+
end
|
155
|
+
end
|
106
156
|
|
107
157
|
# Index consumer pipes by stream name, consumer_name
|
108
158
|
out_pipes = {}
|
109
159
|
|
110
|
-
|
160
|
+
# Check if you are the consumee for a downstream join in order to select the correct pipe
|
111
161
|
if type != "sink"
|
112
162
|
@arc_map[name].each_pair do |stream, destinations|
|
113
163
|
out_pipes[stream] ||= {}
|
164
|
+
|
165
|
+
|
114
166
|
destinations.each do |dest|
|
115
|
-
out_pipes[stream][dest]
|
167
|
+
out_pipes[stream][dest] ||= {}
|
168
|
+
|
169
|
+
# Check for a join at the destination
|
170
|
+
if (@node_map[dest]["type"] == "join")
|
171
|
+
@arcs.each do |a|
|
172
|
+
if (a["dest"] == dest && a["origin"] == name)
|
173
|
+
# Left Side
|
174
|
+
if (a["left"] == 1)
|
175
|
+
out_pipes[stream][dest]["wr_parent_1"] = @operation_pipes[dest]["wr_parent_1"]
|
176
|
+
out_pipes[stream][dest]["rd_parent_1"] = @operation_pipes[dest]["rd_parent_1"]
|
177
|
+
break
|
178
|
+
elsif (a["right"] == 1)
|
179
|
+
out_pipes[stream][dest]["wr_parent_2"] = @operation_pipes[dest]["wr_parent_2"]
|
180
|
+
out_pipes[stream][dest]["rd_parent_2"] = @operation_pipes[dest]["rd_parent_2"]
|
181
|
+
break
|
182
|
+
end
|
183
|
+
end
|
184
|
+
end
|
185
|
+
else
|
186
|
+
out_pipes[stream][dest]["wr_parent_1"] = @operation_pipes[dest]["wr_parent_1"]
|
187
|
+
out_pipes[stream][dest]["rd_parent_1"] = @operation_pipes[dest]["rd_parent_1"]
|
188
|
+
end
|
116
189
|
end
|
117
190
|
end
|
118
191
|
end
|
119
192
|
|
120
193
|
# Run the child process
|
121
|
-
Zillabyte::Runner::MultilangOperation.run(n, dir,
|
122
|
-
|
194
|
+
Zillabyte::Runner::MultilangOperation.run(n, dir, in_pipes, out_pipes, self, meta, options)
|
195
|
+
|
196
|
+
rescue => e
|
197
|
+
display e.message
|
198
|
+
display e.backtrace
|
123
199
|
ensure
|
124
200
|
# Close the reading end of the child
|
125
|
-
|
201
|
+
pipes["rd_child_1"].close()
|
126
202
|
# Close the writing end of the child
|
127
|
-
|
203
|
+
pipes["wr_child_1"].close()
|
204
|
+
|
205
|
+
# Close secondary join child
|
206
|
+
pipes["rd_child_2"].close() if pipes["rd_child_2"]
|
207
|
+
pipes["wr_child_2"].close() if pipes["wr_child_2"]
|
208
|
+
|
128
209
|
exit!(-1)
|
129
210
|
end
|
130
211
|
|
@@ -148,17 +229,24 @@ class Zillabyte::Runner::AppRunner < Zillabyte::Command::Base
|
|
148
229
|
next
|
149
230
|
end
|
150
231
|
# Send tuple to source
|
151
|
-
@operation_pipes["source_1"][
|
232
|
+
@operation_pipes["source_1"]["wr_parent_1"].puts msg
|
152
233
|
end
|
153
234
|
end
|
154
|
-
|
235
|
+
rescue => e
|
236
|
+
display e.message
|
237
|
+
display e.backtrace
|
155
238
|
ensure
|
156
239
|
Process.waitall()
|
157
240
|
@operation_pipes.each do |name, pipes|
|
158
241
|
#Close the writing end of the parent
|
159
|
-
pipes[
|
242
|
+
pipes["wr_parent_1"].close()
|
160
243
|
# Close the reading end of the parent
|
161
|
-
pipes[
|
244
|
+
pipes["rd_parent_1"].close()
|
245
|
+
|
246
|
+
# Close secondary join parent
|
247
|
+
pipes["wr_parent_2"].close() if pipes["wr_parent_2"]
|
248
|
+
pipes["rd_parent_2"].close() if pipes["rd_parent_2"]
|
249
|
+
|
162
250
|
end
|
163
251
|
end
|
164
252
|
|
@@ -11,14 +11,13 @@ class Zillabyte::Runner::ComponentOperation
|
|
11
11
|
ENDMARKER = "\nend\n"
|
12
12
|
|
13
13
|
# Run the operation
|
14
|
-
def self.run(node, dir,
|
15
|
-
|
14
|
+
def self.run(node, dir, consumee_pipes, consumer_pipes, tester, meta, options = {})
|
16
15
|
|
17
16
|
@__node = node
|
18
17
|
@__name = node["name"]
|
19
18
|
@__type = node["type"]
|
20
19
|
@__dir = dir
|
21
|
-
@
|
20
|
+
@__consumee_pipes = consumee_pipes
|
22
21
|
@__consumer_pipes = consumer_pipes
|
23
22
|
@__tester = tester
|
24
23
|
|
@@ -43,7 +42,7 @@ class Zillabyte::Runner::ComponentOperation
|
|
43
42
|
|
44
43
|
# Component outputs act in same manner as sinks
|
45
44
|
else
|
46
|
-
Zillabyte::Runner::MultilangOperation.run(node, dir,
|
45
|
+
Zillabyte::Runner::MultilangOperation.run(node, dir, consumee_pipes, consumer_pipes, tester, meta, options)
|
47
46
|
end
|
48
47
|
rescue => e
|
49
48
|
cdisplay e.message
|
@@ -76,14 +75,7 @@ class Zillabyte::Runner::ComponentOperation
|
|
76
75
|
end
|
77
76
|
|
78
77
|
# Index streams and consumers by their pipes for lookup
|
79
|
-
consumer_hash =
|
80
|
-
@__emit_queues.each_pair do |stream, consumers|
|
81
|
-
consumers.each_key do |consumer|
|
82
|
-
read_stream = @__consumer_pipes[stream][consumer][:rd_parent]
|
83
|
-
consumer_hash[read_stream] = {:stream => stream, :consumer => consumer}
|
84
|
-
end
|
85
|
-
end
|
86
|
-
|
78
|
+
consumer_hash = build_consumer_hash()
|
87
79
|
|
88
80
|
# Send first tuple
|
89
81
|
@__emit_queues.each_pair do |stream, consumers|
|
@@ -119,8 +111,8 @@ class Zillabyte::Runner::ComponentOperation
|
|
119
111
|
if tuple_json.nil?
|
120
112
|
write_stream = get_write_stream(stream, consumer)
|
121
113
|
cdisplay "ending cycle for #{consumer}"
|
122
|
-
|
123
|
-
|
114
|
+
send_command_tuple(stream, consumer, END_CYCLE_MESSAGE)
|
115
|
+
send_command_tuple(stream, consumer, DONE_MESSAGE)
|
124
116
|
|
125
117
|
else
|
126
118
|
# Emit tuple to consumer
|
@@ -138,16 +130,15 @@ class Zillabyte::Runner::ComponentOperation
|
|
138
130
|
end
|
139
131
|
|
140
132
|
else
|
141
|
-
stdin = @
|
133
|
+
stdin = @__consumee_pipes["rd_child_1"]
|
142
134
|
loop do
|
143
135
|
|
144
136
|
msg = stdin.gets
|
145
137
|
if msg == "end\n"
|
146
138
|
@__consumer_pipes.each_pair do |stream, consumers|
|
147
139
|
consumers.each_pair do |consumer, pipe|
|
148
|
-
|
149
|
-
|
150
|
-
write_message(write_stream, DONE_MESSAGE)
|
140
|
+
send_command_tuple(stream, consumer, END_CYCLE_MESSAGE)
|
141
|
+
send_command_tuple(stream, consumer, DONE_MESSAGE)
|
151
142
|
end
|
152
143
|
end
|
153
144
|
|
@@ -187,13 +178,7 @@ class Zillabyte::Runner::ComponentOperation
|
|
187
178
|
def self.run_rpc_component()
|
188
179
|
|
189
180
|
# Index streams and consumers by their pipes for lookup
|
190
|
-
consumer_hash =
|
191
|
-
@__emit_queues.each_pair do |stream, consumers|
|
192
|
-
consumers.each_key do |consumer|
|
193
|
-
read_stream = @__consumer_pipes[stream][consumer][:rd_parent]
|
194
|
-
consumer_hash[read_stream] = {:stream => stream, :consumer => consumer}
|
195
|
-
end
|
196
|
-
end
|
181
|
+
consumer_hash = build_consumer_hash()
|
197
182
|
|
198
183
|
# Keep track of how many consumers to handle before exiting
|
199
184
|
consumers_running = consumer_hash.keys.length
|
@@ -204,7 +189,7 @@ class Zillabyte::Runner::ComponentOperation
|
|
204
189
|
|
205
190
|
# TODO multiple inputs
|
206
191
|
# The input component(singular at the moment)
|
207
|
-
read_streams = consumer_hash.keys.concat [@
|
192
|
+
read_streams = consumer_hash.keys.concat [@__consumee_pipes["rd_child_1"]]
|
208
193
|
|
209
194
|
# Start communication with API
|
210
195
|
api = @__tester.session.api
|
@@ -335,7 +320,7 @@ class Zillabyte::Runner::ComponentOperation
|
|
335
320
|
end
|
336
321
|
|
337
322
|
# Ask for next tuple
|
338
|
-
write_message(@
|
323
|
+
write_message(@__consumee_pipes["wr_child_1"], NEXT_MESSAGE)
|
339
324
|
|
340
325
|
|
341
326
|
# End cycle
|
@@ -352,8 +337,7 @@ class Zillabyte::Runner::ComponentOperation
|
|
352
337
|
|
353
338
|
# End cycle for consumer if it has processed all tuples
|
354
339
|
if tuple_json.nil? && end_cycle_received
|
355
|
-
|
356
|
-
write_message(write_stream, END_CYCLE_MESSAGE)
|
340
|
+
send_command_tuple(stream, consumer, END_CYCLE_MESSAGE)
|
357
341
|
consumers_running -= 1
|
358
342
|
if consumers_running == 0
|
359
343
|
break
|
@@ -489,11 +473,42 @@ class Zillabyte::Runner::ComponentOperation
|
|
489
473
|
end
|
490
474
|
end
|
491
475
|
|
476
|
+
|
477
|
+
# Build the hash of consumer streams for lookup when receiving responses
|
478
|
+
def self.build_consumer_hash()
|
479
|
+
consumer_hash = {}
|
480
|
+
@__emit_queues.each_pair do |stream, consumers|
|
481
|
+
consumers.each_key do |consumer|
|
482
|
+
|
483
|
+
pipes = @__consumer_pipes[stream][consumer]
|
484
|
+
if pipes.has_key? "rd_parent_1"
|
485
|
+
read_stream = pipes["rd_parent_1"]
|
486
|
+
consumer_hash[read_stream] = {:stream => stream, :consumer => consumer}
|
487
|
+
|
488
|
+
elsif pipes.has_key? "rd_parent_2"
|
489
|
+
read_stream = pipes["rd_parent_2"]
|
490
|
+
consumer_hash[read_stream] = {:stream => stream, :consumer => consumer}
|
491
|
+
end
|
492
|
+
end
|
493
|
+
end
|
494
|
+
|
495
|
+
return consumer_hash
|
496
|
+
end
|
497
|
+
|
492
498
|
# Send object to every consumer of the operation, regardless of stream
|
493
499
|
def self.send_to_consumers(json_obj)
|
494
500
|
@__consumer_pipes.each_pair do |stream, consumers|
|
495
501
|
consumers.each_pair do |consumer, pipe|
|
496
|
-
|
502
|
+
|
503
|
+
# Single or Left hand pipe
|
504
|
+
if (pipe.has_key? "wr_parent_1")
|
505
|
+
write_stream = get_write_stream(stream, consumer, 1)
|
506
|
+
write_message(write_stream, json_obj)
|
507
|
+
elsif (pipe.has_key? "wr_parent_2")
|
508
|
+
write_stream = get_write_stream(stream, consumer, 2)
|
509
|
+
write_message(write_stream, json_obj)
|
510
|
+
end
|
511
|
+
|
497
512
|
cdisplay "emitted #{json_obj} to #{consumer}"
|
498
513
|
end
|
499
514
|
end
|
@@ -501,8 +516,9 @@ class Zillabyte::Runner::ComponentOperation
|
|
501
516
|
|
502
517
|
|
503
518
|
# Get the write pipe of the stream consumer
|
504
|
-
def self.get_write_stream(stream, consumer)
|
505
|
-
|
519
|
+
def self.get_write_stream(stream, consumer, number=1)
|
520
|
+
wr_pipe = "wr_parent_" + number.to_s
|
521
|
+
@__consumer_pipes[stream][consumer][wr_pipe]
|
506
522
|
end
|
507
523
|
|
508
524
|
|
@@ -512,6 +528,22 @@ class Zillabyte::Runner::ComponentOperation
|
|
512
528
|
end
|
513
529
|
|
514
530
|
|
531
|
+
def self.send_command_tuple(stream, consumer, json_obj)
|
532
|
+
pipe = @__consumer_pipes[stream][consumer]
|
533
|
+
# Single or Left hand pipe
|
534
|
+
if (pipe.has_key? "wr_parent_1")
|
535
|
+
write_stream = get_write_stream(stream, consumer, 1)
|
536
|
+
write_message(write_stream, json_obj)
|
537
|
+
|
538
|
+
# Right hand pipe
|
539
|
+
elsif (pipe.has_key? "wr_parent_2")
|
540
|
+
write_stream = get_write_stream(stream, consumer, 2)
|
541
|
+
write_message(write_stream, json_obj)
|
542
|
+
end
|
543
|
+
@__emit_queues[stream][consumer][:ready] = false
|
544
|
+
end
|
545
|
+
|
546
|
+
|
515
547
|
# Emit tuple_json to the consumer of a stream
|
516
548
|
def self.emit_consumer_tuple(stream, consumer, tuple_json)
|
517
549
|
begin
|
@@ -519,8 +551,19 @@ class Zillabyte::Runner::ComponentOperation
|
|
519
551
|
rescue JSON::ParserError
|
520
552
|
cdisplay "Error: invalid JSON"
|
521
553
|
end
|
522
|
-
|
523
|
-
|
554
|
+
|
555
|
+
pipe = @__consumer_pipes[stream][consumer]
|
556
|
+
# Single or Left hand pipe
|
557
|
+
if (pipe.has_key? "wr_parent_1")
|
558
|
+
write_stream = get_write_stream(stream, consumer, 1)
|
559
|
+
write_message(write_stream, tuple_json)
|
560
|
+
|
561
|
+
# Right hand pipe
|
562
|
+
elsif (pipe.has_key? "wr_parent_2")
|
563
|
+
write_stream = get_write_stream(stream, consumer, 2)
|
564
|
+
write_message(write_stream, tuple_json)
|
565
|
+
end
|
566
|
+
|
524
567
|
@__emit_queues[stream][consumer][:ready] = false
|
525
568
|
cdisplay "emitted tuple #{display_json} to #{consumer} "
|
526
569
|
end
|