Inspirel banner

YAMI4 Tip #2 - Default Objects

YAMI4 offers some object-oriented concepts that make the design of distributed systems easier and more structured - we can describe the message traffic as flowing not just between two programs, but rather to particular objects that are message recipients. This is why all example programs use some readable message target names like "calculator" or "printer" - these represent logical message destinations.

Taking from example C++ calculator programs, the server can register one or more logical destinations like this:

        server_agent.register_object("calculator", call);

where "calculator" is the name of new destination and call is a callable entity that will receive the incoming message.

The client program can then send his messages to that particular destination:

        std::auto_ptr om(
            client_agent.send(server_address,
                "calculator", "calculate", params));

and the "calculator" name is what allows both sides to match.

There can be many logical destination objects in the server and the objects can be added and removed at runtime. Moreover, they don't even have to be backed by physically distinct class instances or distinct callbacks - actually, serving multiple logical objects from a single physical program entity opens many interesting scenarios for resource management.

The interesting thing here is what happens when the client tries to send the message to a logical object that does not exist - which means the object that was not registered by the server. By default such a message will be automatically rejected (the client will see appropriate message state and reason) and the server code will not even know that such a message was automatically processed by the agent.

It is possible to register the default object that will act as a "catch-all" destination for all those messages that could not match to any specific object. The default object can be registered with "*" as a wildcard name:

        server_agent.register_object("*", default_call);

From now on, the default_call entity (whatever it is - function or functor) will be invoked when there is an incoming message that does not match any of the registered logical objects.

There can be several reasons to use default objects:

Default objects are implemented by YAMI4 in the same way in all high-level libraries, so these motivations and design principles are language-neutral.

Previous tip: Connection Timeouts

Next tip: Shallow Parameters