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

name[RW]

The name of the port. @return [String]

uuid[RW]

The UUID of the port. @return [String]

Public Class Methods

new(component, args = {}) click to toggle source

@param component [Component] the component the port belongs to @param args [Hash] supported args are :uuid and :name

Calls superclass method 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

[](key) click to toggle source

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
add_connection(key, connection) click to toggle source

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
all_connections() click to toggle source

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(key, receiver) { || ... } click to toggle source

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
connect!() click to toggle source

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
connections_for(key) click to toggle source

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
direct_connect(key = nil, other_port) click to toggle source

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
each() { |connections| ... } click to toggle source

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
keys() click to toggle source

A list of connected keys. @return [Array<String>]

# File lib/rflow/component/port.rb, line 210
def keys
  @connections_for.keys
end
remove_connection(key, connection) click to toggle source

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
send_message(message) click to toggle source

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