rflow 1.0.0a5 → 1.0.0a6

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: ef1b7b3ae0fb683425fec5c44f0c1d39f7f29935
4
- data.tar.gz: acc3b05b5b26d9286fe51c4c0d3e6a028d9c0f46
3
+ metadata.gz: b664558de8f5e223ca41a0b4ead08935897a5388
4
+ data.tar.gz: e0df2c50c8e75a3cb3291b0a8474a7ed1ecc7485
5
5
  SHA512:
6
- metadata.gz: d040a8d35aff247bd4200c2b5ac8f4ba4c9b8b9dc48a31292e68db1db07cc3e568a2a33067c600f54d99e3346bc60640f7338f395d9c9ddbc5caf7c7f725145d
7
- data.tar.gz: 3f8b6b770e61ad2eb2ad17aa647d516d761d042c38491d958bbcb7b85f1b0d91fc80fa0cdd9d5a6e27af1308d05c2c3324c2e9a595bb1b076eedbb781c1c66a8
6
+ metadata.gz: 556cc4a467b582aa0c1a5e16dd908c6bf3db66818371ff9beba420c141957f694e9d1729c0baa1da35c398a81cfb49b7debd572c8fd6eee207c4980a4c7fac72
7
+ data.tar.gz: cd044c4905c4c181d66df6a495d1b9729ae4e88cf831e6470f37a4e9a94ad28043b3bac5dd07fc4aa13ab4161fcb4b5ab3b3c184623c90b22144e0c9c26460c6
@@ -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 do |key, connections|
142
- connections.each do |connection|
143
- connection.connect_input!
144
- @connected = true
145
- end
146
- end
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 do |key, connections|
163
- connections.each do |connection|
164
- connection.connect_output!
165
- @connected = true
166
- end
167
- end
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,
@@ -103,7 +103,7 @@ class RFlow
103
103
  end
104
104
 
105
105
  # for testing purposes
106
- class NullConfiguration
106
+ class NullConnectionConfiguration
107
107
  attr_accessor :name, :uuid, :options, :input_port_key, :output_port_key, :delivery
108
108
  end
109
109
  end
@@ -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
- connection_type = many_to_many ? RFlow::Configuration::BrokeredZMQConnection : RFlow::Configuration::ZMQConnection
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}"
@@ -69,7 +69,7 @@ class RFlow
69
69
  attr_accessor :messages
70
70
 
71
71
  def initialize
72
- super(RFlow::Configuration::NullConfiguration.new)
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::NullConfiguration.new)
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::NullConfiguration.new)
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
@@ -1,3 +1,3 @@
1
1
  class RFlow
2
- VERSION = "1.0.0a5"
2
+ VERSION = "1.0.0a6"
3
3
  end
@@ -2,67 +2,102 @@ require 'spec_helper'
2
2
 
3
3
  class RFlow
4
4
  class Component
5
- describe Port do
6
- it "should not be connected" do
7
- expect(described_class.new(nil)).not_to be_connected
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
- describe HashPort do
12
- it "should not be connected" do
13
- expect(described_class.new(nil)).not_to be_connected
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
- describe InputPort do
18
- context "#connect!" do
19
- it "should be connected" do
20
- connection = double('connection')
21
- allow(connection).to receive(:name)
22
- allow(connection).to receive(:uuid)
23
- allow(connection).to receive(:input_port_key)
24
- expect(connection).to receive(:connect_input!)
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
- described_class.new(nil).tap do |port|
27
- port.add_connection(nil, connection)
28
- expect(port).not_to be_connected
29
- port.connect!
30
- expect(port).to be_connected
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
- context "#(add|remove)_connection" do
36
- it "should remove the connection" do
37
- connection = double('connection')
38
- allow(connection).to receive(:name)
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
- described_class.new(nil).tap do |port|
43
- port.add_connection(nil, connection)
44
- expect(port[nil]).to include connection
45
- port.remove_connection(nil, connection)
46
- expect(port[nil]).not_to include connection
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
- describe OutputPort do
53
- context "#connect!" do
54
- it "should be connected" do
55
- connection = double('connection')
56
- allow(connection).to receive(:name)
57
- allow(connection).to receive(:uuid)
58
- allow(connection).to receive(:input_port_key)
59
- expect(connection).to receive(:connect_output!)
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
- described_class.new(nil).tap do |port|
62
- port.add_connection(nil, connection)
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 => 1 do |s|
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.0a5
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-24 00:00:00.000000000 Z
11
+ date: 2014-06-26 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: uuidtools