Reactive messaging in Prova is a fundamental part of the system that is used for organising distributed Prova engines into a network of communicating agents. It is also a foundation of the rule-based workflow and event processing functionality. The roots of the Prova reactive messaging capabilities lie in the series of papers written on so called Vivid Agents by Michael Schroeder and Gerd Wagner. A Prova agent is an instance of a running rulebase that includes message passing primitives.
Prova agents communicate using what we call protocols. Inside a Prova agent rulebase, a protocol is just an argument passed to message passing primitives, both for receiving and sending messages, and a decoration attached to the actual messages. The distribution aspect of Prova agents is consequently not part of the Prova agent rulebases code at all, with the remote protocol, called esb, being one of those protocols that is provided by the Java container running the Prova engine.
The key principle used for message processing is pattern matching. This type of message handling is quite universally known and used in such communication languages as Erlang. The Prova pattern matching is similar but extends the Erlang type of pattern matching in a number of ways.
Prova message passing primitives use other standard, position-based, metadata attributes, in addition to the message protocol. These are ordered parameters to both message sending and receiving primitives:
- XID - conversation id of the message;
- Protocol - name of the message passing protocol;
- Destination (on sending) or Sender (on receiving);
- Performative - the message type broadly characterising the meaning of the message;
- Payload - a Prova list containing the actual content of the message.
All these parameters can be used for constraining the reactions on the receiving side, thereby simplifying the coding of inter-agent communication. You specify all those parameters you want to be fixed as constants and leave those that require further reasoning about as free variables that will be assigned to when the actual message arrives. Sending messages reverses this process, so that you include the same above parameters as part of the message sending builtins, sendMsg or sendMsgSync.
As described in Using reaction rules for receiving messages, there are two types of reaction rules: global, that are active for the whole lifetime of a rulebase, and inline, which are far more dynamic and whose scope can be controlled in a very flexible way, for example, by disabling and re-enabling them back again based on other reactions. Annotations for message receiving shows how to set a timeout on an inline reaction.
Prova seeks to minimize syntactic overload that is common to a number of modern asynchronous programming frameworks as well as agent and functional languages. The syntax economy being the utmost priority, it becomes far easier to maintain the code, for example re-ordering the reactions or making them non-deterministic with just one extra body literal. The code is also far easier to auto-generate from graphical or wizard-driven front-ends.
Reactive messaging on Prova is based on conversations. The conversation id is always carried with messages, it allows many conversations to be executing in parallel at the same time and it also forms the basis of the Prova concurrency model that extends Actors with the ability to "pin" the same (and typically more than one) conversation to the same thread (see Concurrent reactive messaging).
Event processing in Prova is based on collective group reactions. Such reactions do not work alone, instead many reactions are instantiated and respond to incoming messages collectively, for example, watching for a particular event pattern in the inbound message stream(s).