zillabyte-cli 0.1.18 → 0.1.19
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.
- 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
|