class RFlow::Component::HashPort
Allows for a list of connections to be assigned to each port/key combination. Note that binding an input port to an un-indexed output port will result in messages from all indexed connections being received. Similarly, sending to an unindexed port will result in the same message being sent to all indexed connections.
Attributes
The name of the port. @return [String]
The UUID of the port. @return [String]
Public Class Methods
@param component [Component] the component the port belongs to @param args [Hash] supported args are :uuid
and :name
RFlow::Component::Port::new
# File lib/rflow/component/port.rb, line 124 def initialize(component, args = {}) super(component) self.uuid = args[:uuid] self.name = args[:name] @connections_for = Hash.new {|hash, key| hash[key] = []} end
Public Instance Methods
Get the subport for a given key, which can be used to send messages or direct connection. @param key [String] the key to subscript with @return [HashSubPort]
# File lib/rflow/component/port.rb, line 135 def [](key) HashSubPort.new(self, key) end
Adds a connection for a given key. @param key [String] the key to subscript with @param connection [Connection] the connection to add @return [void]
# File lib/rflow/component/port.rb, line 158 def add_connection(key, connection) RFlow.logger.debug "Attaching #{connection.class.name} connection '#{connection.name}' (#{connection.uuid}) to port '#{name}' (#{uuid}), key '#{connection.input_port_key}'" @connections_for[key] << connection @all_connections = nil end
Retrieve all connections to the port, regardless of key. The resulting Array
also supports +send_message(message)+ which will deliver the message on all connections. @return [Array<Connection>]
# File lib/rflow/component/port.rb, line 235 def all_connections @all_connections ||= @connections_for.values.flatten.uniq.extend(ConnectionCollection) end
Collect messages being sent to this port in a {MessageCollectingConnection} for retrieval later, usually for unit testing purposes. +yield+s after establishing the new connection. @param key [String] the key to subscript with @param receiver [Array] array in which to place arriving messages @return [MessageCollectingConnection]
# File lib/rflow/component/port.rb, line 180 def collect_messages(key, receiver) begin connection = RFlow::MessageCollectingConnection.new.tap do |c| c.messages = receiver end add_connection key, connection yield if block_given? connection ensure remove_connection key, connection if connection && block_given? end end
Override in subclasses to handle establishing the connection. @return [void]
# File lib/rflow/component/port.rb, line 229 def connect!; raise NotImplementedError, 'Raw ports do not know which direction to connect'; end
Returns all the connections that should be sent/received on this subport. Merges the nil
-keyed port (i.e. any connections for a port without a key) to those specific for the key, so should only be used to read a list of connections, not to add new ones. Use {add_connection} to add a new connection for a given key. @param key [String] the key to subscript with @return [Array<Connection>]
# File lib/rflow/component/port.rb, line 147 def connections_for(key) case key when nil; @connections_for[nil] else @connections_for[key] + @connections_for[nil] end end
Directly connect this port to another port. If it's an input port, forward messages to that input port; if it's an output port, forward messages so they appear to come from that output port. @param key [String] the key to subscript with @param other_port [Port] the port to forward to @return [void]
# File lib/rflow/component/port.rb, line 200 def direct_connect(key = nil, other_port) case other_port when InputPort; add_connection key, ForwardToInputPort.new(other_port) when OutputPort; add_connection key, ForwardToOutputPort.new(other_port) else raise ArgumentError, "Unknown port type #{other_port.class.name}" end end
Enumerate all connections, +yield+ing each. @return [Array<Connection>]
# File lib/rflow/component/port.rb, line 216 def each @connections_for.values.each {|connections| yield connections } end
A list of connected keys. @return [Array<String>]
# File lib/rflow/component/port.rb, line 210 def keys @connections_for.keys end
Removes a connection from a given key. @param key [String] the key to subscript with @param connection [Connection] the connection to remove @return [void]
# File lib/rflow/component/port.rb, line 168 def remove_connection(key, connection) RFlow.logger.debug "Removing #{connection.class.name} connection '#{connection.name}' (#{connection.uuid}) from port '#{name}' (#{uuid}), key '#{connection.input_port_key}'" @connections_for[key].delete(connection) @all_connections = nil end
Override in subclasses to actually send messages places. @param message [Message] the message to send @return [void]
# File lib/rflow/component/port.rb, line 223 def send_message(message) raise NotImplementedError, 'Raw ports do not know how to send messages' end