Changes to GossipRouter in 2.8 ============================== Author: Bela Ban Motivation ---------- The changes are mainly due to logical addresses and shared transport. TCPGOSSIP currently doesn't work, as the GossipRouter doesn't return logical addresses *and* their associated physical addresses, but only returns logical addresses (UUIDs) [1]. In TUNNEL, RouterStubs are conceptually associated with a single channel, and cannot process traffic from multiple channels on top of a shared transport. [1] https://jira.jboss.org/jira/browse/JGRP-1005 [2] https://jira.jboss.org/jira/browse/JGRP-924 Design overview --------------- A RouterStub will simply establish a TCP connection with a GossipRouter, but doesn't send the CONNECT message on socket establishment. This is typically done in init() of TUNNEL (or TCPGOSSIP). On channel connection, a CONNECT(groupname, logical_addr, logical_name, physical_addresses) is sent to the GossipRouter. On a GET-MEMBERS(groupname), the GR returns a list of elements. On a ROUTE(groupname, logical_addr, message), the GR pick the single destination (if logical-addr is not null) and routes the message. If logical_addr is null, then the GR routes the message to all members keyed by groupname. The GossipRouter maintains the following data structures: - RoutingTable: - A hashmap with groupnames as keys and hashmaps as values - The 2nd level hashmaps have logical addresses as keys and ConnectionHandlers as values - A ConnectionHandler represent a physical connection to a client. It has a thread listening for messages on the input stream, and it also has a list of logical_addrs from which it received CONNECT messages. - When the socket in the ConnectionHandler is closed by the peer, we remove all entries associated with all logical_addrs of ConnectionHandler from the other data structures. - AddressMappings: - Maintains a hashmap with logical_addrs as keys and the physical_addrs as value - This is used to map logical addresses to their physical addresses, and is only used by TCPGOSSIP Implementation -------------- RouterStub ---------- - When started, the RouterStub establishes a socket to the GossipRouter's address:port given - When the connection is closed by the GR, the stub goes into reconnecting mode. When reconnected, it issues a notification so registered listeners can send a CONNECT (see below) to the GR again - When the CONNECT event is received by TUNNEL / TCPGOSSIP, RouterStub.connect() is called with - the groupname - the logical address - the logical name - a list of physical addresses (might be null, only used by TCPGOSSIP) - This generates a CONNECT message which is sent to the GossipRouter GossipRouter ------------ - On accept(): - Create a new ConnectionHandler on a new thread (from the thread pool) - This stores the client socket, input and output stream, then listens on the input stream [- We might add the ConnectionHandler to a separate list, just to keep track of open connections] - On peer (RouterStub) closing the socket: - The ConnectionHandler gets an exception when listening on the input stream - We remove the entries in connection-list from all tables - On CONNECT(groupname, logical_addr, logical_name, physical_addrs) [received by ConnectionHandler.run()]: - The ConnectionHandler adds the logical address to its connection-list - An entry is added to RoutingTable under groupname, and the value (hashmap) is updated: - key is the logical addr, value the ConnectionHandler (this) - If CONNECT ships with non-null physical_addrs, then an entry is added to AddressMappings - On DISCONNECT(logical_addr): - Remove the entry for logical_addr from all tables (RoutingTable, AddressMappings) - Do *not* close the socket in ConnectionHandler: others may still be connected through the same connection ! - On GET_MEMBERS(groupname): - Grabs the members for groupname (from RoutingTable and AddressMappings) and passes them back, for each member: - The logical address - The logical name - (if available) a list of physical addresses - On ROUTE(groupname, dest, message): - If dest == null (multicast): - Grab all ConnectionHandler's from RoutingTable for groupname and send the message to all - Else (unicast) - Find the ConnectionHandler keyed by 'dest' and send the message to it TUNNEL ------ - On stub reconnect: - Send a CONNECT message. With a shared transort, this has to be done for all channels sharing the transport