Skip navigation links

Package com.americati.sss

"Safe Smart Switching" infrastructure is a message switching engine which helps in the construction of concurrent network applications with emphasis in messaging and transactions.

See: Description

Package com.americati.sss Description

"Safe Smart Switching" infrastructure is a message switching engine which helps in the construction of concurrent network applications with emphasis in messaging and transactions. A user application skeleton is as follows:
                S3 s3 = S3Factory.getInstance();
                s3.defineMessageHandler("router", routerHandler);
                // define an input queue
                S3ConfigCommand iq = S3ConfigCommandBuilder.startBuild("iq").
                                attr("id", "unique").
                                attr("handler", "router").
                                build();
                S3ConfigResponse rc = s3.configure(iq);
                if(rc.getCode() != S3Constants.OK) { handle_failure()... }
                // define a server
                S3ConfigCommand sc = S3ConfigCommandBuilder.startBuild("sc").
                                attr("id", "input").
                                attr("iq", "unique").
                                attr("framer", "2b").
                                attr("listen-port", "7890").build();
                s3.configure(sc);
 
The user application should provide:

The connections are of client and server types: clients attempt to connect to a remote peer (and retry as needed) while the servers expect one or more inbound connections.

After configuration, the connections can be handled with S3Connection, which can be specialized into S3Client or S3Server.

When a connection is established (client or server), its incoming messages are added to an "Incoming Queue". The Incoming Queues must be established by the configuration. Several connections can be associated to a single Incoming Queue.

Each of the Incoming Queues can have an associated thread pool which extracts and process the messages (if its pool-size attribute is greater than zero.) Also, every Incoming Queue has an associated "message handler" in charge of processing its messages, as its thread pool allows for. Note that if there is a thread pool with a capacity greater than one, then the messages could be processed out of order with respect to its network input.

The pool-size attribute could be very useful: if the message handlers take a variable time to execute, it could be convenient a mutithreaded execution in order to avoid delaying the faster ones.

If an Incoming Queue is filled, then its associated input channels are no longer read. This is effectively a flow control strategy.

It is expected that the message handlers do their work in a quick way (non blocking code.) Those handlers typically end by sending some kind of forward message or response message.

The "output" is implemented by a series of connection-associated Outgoing Queues; for client connections there is exactly one Outgoing Queue, where all outbound messages await to be sent to the net.

But for server connections, a "default" outgoing queue stores the "non-directed" outbound messages (sent without specifying a child id), and also a per-child outgoing queue is used for "directed" outbound messages. These "per-child" queues are created (and dropped) dynamically as the inbound child connections are established or closed.

The messages in the server "default" outgouing queue will be sent to the first available connected child connection.

The message handlers put messages into those Outgoing Queues using one of the following strategies:

The messages are extracted from the Outgoing Queues as long as the destination connections are ready for network writing.

The queues can be configured to "prune" late messages with the "qttl" parameter. While this parameter is specified in milliseconds, note that the "pruning" check time is not guaranteed at all (currently its resolution is about one second.) The pruning is applied only for queues associated to disconnected channels (or without children for server connections.) In the future, the pruning could be unrelated to the channel state.

The framework uses the concept of "connection name" (see S3Connection.getId()) in order to identify each client connection (connected or not), and each server connection (either waiting for incoming connections or connected to several client "childs".) The inbound server childs are identified by a "child UUID" string. In order to send a message to a peer thru a client-type connection, the "connection name" must be specified as "destination" in the S3 methods; for a server-type, this should be complemented with the "child UUID". For servers, If the "child UUID" is not provided, the message will be sent to any "child connection" (which could be useful, for example, if the application limits the inbound connections to one.) See also the description of S3Message.getAttribute(String).

A data flow scheme for established connections (client or server), showing the relative multiplicity of some components:

 
                      *   1        1   1
 NETWORK-->[connection]-->[incoming]-->[message handler]
  INPUT                     queue
                             
                      *   *          1   1
      [message handler]-->[connection]-->[outgoing]-->NETWORK
        or application                    queue(s)    OUTPUT
                                                              
                                                               
 

The 3S instance owns the set of connections (server/client), and each of them must point to some incoming queue for storing the inbound messages; as shown, several connections can point to a single incoming queue (but only to one.) Also, the 3S instance owns the incoming queues, the message handler registry and the connection handler registry. Each of the incoming queues must point to a message handler in the registry. In contrast, the "outgoing queues" are owned by each connection (1-1 relationship.) When a message handler or the application code sends a message to some destination (i.e. to some connection), it is in effect putting a message in its outgoing queue.

Optionally, the connections can be associated to a "connection handler" (not to be confused with the message handlers.) The connection handlers are invoked when the connections change its state. See S3ConnectionHandler for more information. Note that the registry for message handlers is separated from the connection handlers', so in principle they could use the same identification text (though not advisable of course.)

For secure connections see S3Factory.getInstance(S3SecurityContext, java.util.concurrent.ExecutorService) in order to configure TLS.

To shutdown the infrastructure, just call the S3.shutdown(int) method.

For a complete listing of the available attributes for the connections, see the documentation for S3ConfigCommand.

Skip navigation links