Inspirel banner

YAMI4 Tip #7 - Connect Or Not

The YAMI4 messaging system was designed with focus on messages as opposed to sessions or connections (see types of middleware).
Of course, the physicality of distribution should not be entirely hidden from the programmer (see here for more on this), but in order to expose the notion of message in the YAMI4 design, the connection management was pushed to the background.

This is the simplest example of message sending in YAMI4:

agent.send("tcp://address:port", object_name, message_name, parameters);

Yes, that's one line of code and it is enough to send a message to the given network endpoint, directed to some particular logical object and having its name and a set of parameters.

What is hidden in this invocation is the connection management, which is entirely automated and follows these rules:

This simple mechanism is very effective as it does not waste time and resources on creating multiple connections where a single one can handle the message traffic, and it can also handle most intermittent connectivity problems - if the connection gets accidentally closed, it will be automatically renewed with the next message that is sent to the same destination.

There are cases, however, where this automation is counter-productive.

One of such cases is when the direction of messaging between client and server is reversed - when the server needs to send some message back to the client, for example as an implementation of some subscription service. In this case, the complete sequence of events can follow this pattern:

The last point above is where the automatic connection mechanism kicks in - as long as the client is connected, the server will reuse this connection to send updates; but when the client disconnects and the server-side agent removes it from its internal data structures, the client endpoint will suddenly look like a perfect candidate for a new connection. If the server agent attempts to create it just as with any other regular message, the attempt will most likely fail - the original client endpoint was temporary and could not accept incoming connections anyway.
This is when the server should notice the failure and perhaps tear down the subscription or do something else that makes sense for this type of interaction. But the whole effort of creating the connection and processing its failure is wasteful and can even take a significant time due to system-level connection timeouts.

This is exactly the scenario where the programmer should have more control over the connection management - in particular, the programmer should be able to specify that the automatic connection should not be attempted if the connection does not exist. It can be achieved with a separate argument to the send function, which controls the automatic connection scheme:

bool auto_connect = false;
int priority = 0;

agent.send(client_endpoint, object_name, message_name, parameters, priority, auto_connect);

The auto_connect flag above allows to control whether the connection is to be created automatically or if the error should be reported immediately if the given connection does not exist.

This flag is available in all supported programming languages and this strategy is already used in the value publisher classes that provide basic support for the publish-subscribe pattern in YAMI4.

Another case where the automatic connection mechanism can be switched off is in some real-time systems, where the messages are sent in a loop that has strict timing constraints, where the risk of additional delays due to connection timeouts is prohibitive. This is where the auto_connect flag can be useful as well, together with dedicated functions for creating connections explicitly.

The following example shows the basic scheme for such operation:

// initialization phase:

agent.open_connection(server_endpoint);
// ...

// real-time operation phase:
while (true)
{
    // prepare the message:
    // ...

    // send the message:

    bool auto_connect = false;
    int priority = 0;

    agent.send(server_endpoint, object_name, message_name, parameters, priority, auto_connect);

    // ...
}

Above, the automatic connection feature is effectively switched off, which means that no unnecessary delay will be introduced in the loop body, even if the given endpoint gets disconnected, in which case the error will be reported immediately.

Of course, the close_connection function is also available for completeness.

Previous tip: Taking Care Of UDP

Next tip: Easy Sniffer