rflow 1.0.0a5 → 1.0.0a6
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/rflow/component/port.rb +16 -13
- data/lib/rflow/configuration/connection.rb +1 -1
- data/lib/rflow/configuration/ruby_dsl.rb +4 -2
- data/lib/rflow/connection.rb +3 -3
- data/lib/rflow/version.rb +1 -1
- data/spec/rflow/component/port_spec.rb +81 -46
- data/spec/rflow/configuration/ruby_dsl_spec.rb +33 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b664558de8f5e223ca41a0b4ead08935897a5388
|
4
|
+
data.tar.gz: e0df2c50c8e75a3cb3291b0a8474a7ed1ecc7485
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 556cc4a467b582aa0c1a5e16dd908c6bf3db66818371ff9beba420c141957f694e9d1729c0baa1da35c398a81cfb49b7debd572c8fd6eee207c4980a4c7fac72
|
7
|
+
data.tar.gz: cd044c4905c4c181d66df6a495d1b9729ae4e88cf831e6470f37a4e9a94ad28043b3bac5dd07fc4aa13ab4161fcb4b5ab3b3c184623c90b22144e0c9c26460c6
|
data/lib/rflow/component/port.rb
CHANGED
@@ -81,12 +81,14 @@ class RFlow
|
|
81
81
|
def add_connection(key, connection)
|
82
82
|
RFlow.logger.debug "Attaching #{connection.class.name} connection '#{connection.name}' (#{connection.uuid}) to port '#{name}' (#{uuid}), key '#{connection.input_port_key}'"
|
83
83
|
connections_for[key] << connection
|
84
|
+
@all_connections = nil
|
84
85
|
end
|
85
86
|
|
86
87
|
# Removes a connection from a given key
|
87
88
|
def remove_connection(key, connection)
|
88
89
|
RFlow.logger.debug "Removing #{connection.class.name} connection '#{connection.name}' (#{connection.uuid}) from port '#{name}' (#{uuid}), key '#{connection.input_port_key}'"
|
89
90
|
connections_for[key].delete(connection)
|
91
|
+
@all_connections = nil
|
90
92
|
end
|
91
93
|
|
92
94
|
def collect_messages(key, receiver)
|
@@ -130,7 +132,6 @@ class RFlow
|
|
130
132
|
# establish the connection
|
131
133
|
def connect!; raise NotImplementedError, "Raw ports do not know which direction to connect"; end
|
132
134
|
|
133
|
-
private
|
134
135
|
def all_connections
|
135
136
|
@all_connections ||= connections_for.values.flatten.uniq.extend(ConnectionCollection)
|
136
137
|
end
|
@@ -138,12 +139,13 @@ class RFlow
|
|
138
139
|
|
139
140
|
class InputPort < HashPort
|
140
141
|
def connect!
|
141
|
-
connections_for.each
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
142
|
+
connections_for.each {|key, conns| conns.each {|c| c.connect_input! } }
|
143
|
+
@connected = true
|
144
|
+
end
|
145
|
+
|
146
|
+
def add_connection(key, connection)
|
147
|
+
super
|
148
|
+
connection.connect_input! if connected?
|
147
149
|
end
|
148
150
|
|
149
151
|
def recv_callback=(callback)
|
@@ -159,12 +161,13 @@ class RFlow
|
|
159
161
|
|
160
162
|
class OutputPort < HashPort
|
161
163
|
def connect!
|
162
|
-
connections_for.each
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
164
|
+
connections_for.each {|key, conns| conns.each {|c| c.connect_output! } }
|
165
|
+
@connected = true
|
166
|
+
end
|
167
|
+
|
168
|
+
def add_connection(key, connection)
|
169
|
+
super
|
170
|
+
connection.connect_output! if connected?
|
168
171
|
end
|
169
172
|
|
170
173
|
# Send a message to all connections on all keys for this port,
|
@@ -190,13 +190,15 @@ class RFlow
|
|
190
190
|
output_shards = output_component.shard.count
|
191
191
|
input_shards = input_component.shard.count
|
192
192
|
|
193
|
+
broadcast_connection = spec[:delivery] == 'broadcast'
|
193
194
|
in_shard_connection = output_component.shard == input_component.shard
|
194
195
|
one_to_one = output_shards == 1 && input_shards == 1
|
195
196
|
one_to_many = output_shards == 1 && input_shards > 1
|
196
197
|
many_to_one = output_shards > 1 && input_shards == 1
|
197
198
|
many_to_many = output_shards > 1 && input_shards > 1
|
198
199
|
|
199
|
-
|
200
|
+
use_broker = many_to_many && (broadcast_connection || !in_shard_connection)
|
201
|
+
connection_type = use_broker ? RFlow::Configuration::BrokeredZMQConnection : RFlow::Configuration::ZMQConnection
|
200
202
|
|
201
203
|
conn = connection_type.create!(:name => spec[:name],
|
202
204
|
:delivery => spec[:delivery],
|
@@ -206,7 +208,7 @@ class RFlow
|
|
206
208
|
:input_port => input_port)
|
207
209
|
|
208
210
|
# bind on the cardinality-1 side, connect on the cardinality-n side
|
209
|
-
if in_shard_connection
|
211
|
+
if in_shard_connection && !use_broker
|
210
212
|
conn.options['output_responsibility'] = 'connect'
|
211
213
|
conn.options['input_responsibility'] = 'bind'
|
212
214
|
conn.options['output_address'] = "inproc://rflow.#{conn.uuid}"
|
data/lib/rflow/connection.rb
CHANGED
@@ -69,7 +69,7 @@ class RFlow
|
|
69
69
|
attr_accessor :messages
|
70
70
|
|
71
71
|
def initialize
|
72
|
-
super(RFlow::Configuration::
|
72
|
+
super(RFlow::Configuration::NullConnectionConfiguration.new)
|
73
73
|
@messages = []
|
74
74
|
end
|
75
75
|
|
@@ -84,7 +84,7 @@ class RFlow
|
|
84
84
|
# making the internal component visible to the larger RFlow network.
|
85
85
|
class ForwardToOutputPort < Connection
|
86
86
|
def initialize(target_port)
|
87
|
-
super(RFlow::Configuration::
|
87
|
+
super(RFlow::Configuration::NullConnectionConfiguration.new)
|
88
88
|
@target_port = target_port
|
89
89
|
end
|
90
90
|
|
@@ -99,7 +99,7 @@ class RFlow
|
|
99
99
|
# making the internal component visible to the larger RFlow network.
|
100
100
|
class ForwardToInputPort < Connection
|
101
101
|
def initialize(target_port)
|
102
|
-
super(RFlow::Configuration::
|
102
|
+
super(RFlow::Configuration::NullConnectionConfiguration.new)
|
103
103
|
@receiver = target_port.component
|
104
104
|
@target_port = target_port
|
105
105
|
end
|
data/lib/rflow/version.rb
CHANGED
@@ -2,67 +2,102 @@ require 'spec_helper'
|
|
2
2
|
|
3
3
|
class RFlow
|
4
4
|
class Component
|
5
|
-
|
6
|
-
|
7
|
-
|
5
|
+
context "Input and output ports" do
|
6
|
+
let(:connection) { RFlow::Connection.new(RFlow::Configuration::NullConnectionConfiguration.new) }
|
7
|
+
let(:message) { RFlow::Message.new('RFlow::Message::Data::Raw') }
|
8
|
+
|
9
|
+
describe Port do
|
10
|
+
it "should not be connected" do
|
11
|
+
expect(described_class.new(nil)).not_to be_connected
|
12
|
+
end
|
8
13
|
end
|
9
|
-
end
|
10
14
|
|
11
|
-
|
12
|
-
|
13
|
-
|
15
|
+
describe HashPort do
|
16
|
+
it "should not be connected" do
|
17
|
+
expect(described_class.new(nil)).not_to be_connected
|
18
|
+
end
|
14
19
|
end
|
15
|
-
end
|
16
20
|
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
21
|
+
[InputPort, OutputPort].each do |c|
|
22
|
+
describe c do
|
23
|
+
context "#add_connection" do
|
24
|
+
it "should add the connection" do
|
25
|
+
described_class.new(nil).tap do |port|
|
26
|
+
port.add_connection(nil, connection)
|
27
|
+
expect(port[nil]).to include connection
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
25
31
|
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
32
|
+
context "#remove_connection" do
|
33
|
+
it "should remove the connection" do
|
34
|
+
described_class.new(nil).tap do |port|
|
35
|
+
port.add_connection(nil, connection)
|
36
|
+
port.remove_connection(nil, connection)
|
37
|
+
expect(port[nil]).not_to include connection
|
38
|
+
end
|
39
|
+
end
|
31
40
|
end
|
32
41
|
end
|
33
42
|
end
|
34
43
|
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
allow(connection).to receive(:uuid)
|
40
|
-
allow(connection).to receive(:input_port_key)
|
44
|
+
describe InputPort do
|
45
|
+
context "#connect!" do
|
46
|
+
it "should be connected" do
|
47
|
+
expect(connection).to receive(:connect_input!)
|
41
48
|
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
49
|
+
described_class.new(nil).tap do |port|
|
50
|
+
port.add_connection(nil, connection)
|
51
|
+
expect(port).not_to be_connected
|
52
|
+
port.connect!
|
53
|
+
expect(port).to be_connected
|
54
|
+
end
|
47
55
|
end
|
48
56
|
end
|
49
57
|
end
|
50
|
-
end
|
51
58
|
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
59
|
+
describe OutputPort do
|
60
|
+
context "#connect!" do
|
61
|
+
it "should be connected" do
|
62
|
+
expect(connection).to receive(:connect_output!)
|
63
|
+
|
64
|
+
described_class.new(nil).tap do |port|
|
65
|
+
port.add_connection(nil, connection)
|
66
|
+
expect(port).not_to be_connected
|
67
|
+
port.connect!
|
68
|
+
expect(port).to be_connected
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
context "#add_connection" do
|
74
|
+
it "should deliver messages to the new connection" do
|
75
|
+
described_class.new(nil).tap do |port|
|
76
|
+
port.connect!
|
77
|
+
port.all_connections # trigger caching
|
78
|
+
|
79
|
+
expect(connection).to receive(:connect_output!)
|
80
|
+
expect(connection).to receive(:send_message).with(message)
|
81
|
+
port.add_connection(nil, connection)
|
82
|
+
|
83
|
+
port.send_message(message)
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
context "#remove_connection" do
|
89
|
+
it "should not deliver messages to the old connection" do
|
90
|
+
described_class.new(nil).tap do |port|
|
91
|
+
allow(connection).to receive(:connect_output!)
|
92
|
+
port.add_connection(nil, connection)
|
93
|
+
port.connect!
|
94
|
+
port.all_connections # trigger caching
|
95
|
+
|
96
|
+
expect(connection).not_to receive(:send_message)
|
97
|
+
port.remove_connection(nil, connection)
|
60
98
|
|
61
|
-
|
62
|
-
|
63
|
-
expect(port).not_to be_connected
|
64
|
-
port.connect!
|
65
|
-
expect(port).to be_connected
|
99
|
+
port.send_message(message)
|
100
|
+
end
|
66
101
|
end
|
67
102
|
end
|
68
103
|
end
|
@@ -176,7 +176,7 @@ class RFlow
|
|
176
176
|
it "should generate PUSH-PULL inproc ZeroMQ connections for in-shard connections" do
|
177
177
|
described_class.configure do |c|
|
178
178
|
|
179
|
-
c.shard "s1", :process =>
|
179
|
+
c.shard "s1", :process => 2 do |s|
|
180
180
|
s.component 'first', 'First', :opt1 => 'opt1'
|
181
181
|
s.component 'second', 'Second', :opt1 => 'opt1', "opt2" => "opt2"
|
182
182
|
end
|
@@ -415,6 +415,38 @@ class RFlow
|
|
415
415
|
end
|
416
416
|
end
|
417
417
|
|
418
|
+
it "should generate PUB-SUB brokered ZeroMQ connections for many-to-many in-shard broadcast connections" do
|
419
|
+
described_class.configure do |c|
|
420
|
+
|
421
|
+
c.shard "s1", :process => 3 do |s|
|
422
|
+
s.component 'first', 'First', :opt1 => 'opt1'
|
423
|
+
s.component 'second', 'Second', :opt1 => 'opt1', "opt2" => "opt2"
|
424
|
+
end
|
425
|
+
|
426
|
+
c.connect 'first#out' => 'second#in', :delivery => 'broadcast'
|
427
|
+
end
|
428
|
+
|
429
|
+
expect(Shard).to have(1).shards
|
430
|
+
expect(Component).to have(2).components
|
431
|
+
expect(Port).to have(2).ports
|
432
|
+
expect(Connection).to have(1).connections
|
433
|
+
|
434
|
+
Connection.first.tap do |conn|
|
435
|
+
expect(conn.type).to eq('RFlow::Configuration::BrokeredZMQConnection')
|
436
|
+
expect(conn.name).to eq('first#out=>second#in')
|
437
|
+
expect(conn.output_port_key).to be_nil
|
438
|
+
expect(conn.input_port_key).to be_nil
|
439
|
+
conn.options.tap do |opts|
|
440
|
+
expect(opts['output_socket_type']).to eq('PUB')
|
441
|
+
expect(opts['output_address']).to eq("ipc://rflow.#{conn.uuid}.in")
|
442
|
+
expect(opts['output_responsibility']).to eq('connect')
|
443
|
+
expect(opts['input_socket_type']).to eq('SUB')
|
444
|
+
expect(opts['input_address']).to eq("ipc://rflow.#{conn.uuid}.out")
|
445
|
+
expect(opts['input_responsibility']).to eq('connect')
|
446
|
+
end
|
447
|
+
end
|
448
|
+
end
|
449
|
+
|
418
450
|
it "should not allow two components with the same name" do
|
419
451
|
expect {
|
420
452
|
described_class.configure do |c|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rflow
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.0a6
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Michael L. Artz
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-06-
|
11
|
+
date: 2014-06-26 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: uuidtools
|