Skip to end of metadata
Go to start of metadata

Prova agents execute protocols and send and receive messages asynchronously. The rcvMsg and rcvMult builtins do not block the processing thread but instead immediately release it, preserving all the current rule context so that when a matching message arrives, the processing resumes as though it had never been interrupted. Now the big question is, on what thread the processing is resumed?

Prova engine runs on the main thread and two additional thread pools: a conversation thread pool and a task thread pool. All common goals are run on the main thread but the thread pool a message reaction initiated by rcvMsg/rcvMult runs on is chosen by the protocol value passed to an inline reaction rcvMsg/rcvMult that receives a message initiating the goal processing (remember message reactions are goals): the self protocol now targets specifically the main thread, the async protocol targets the conversation pool, and the task protocol targets the task pool. The difference between the two thread pools is that in the async case, the particular thread from the conversation pool is uniquely chosen based on the conversation-id XID passed with the inbound message. This means that messages belonging to the same conversation are always processed on the same thread. The added benefit of this is that any local data in context of the rule containing rcvMsg are processed only on one thread which reduces context switching on multi-core architectures. The choice of the thread in the task pool is completely random.

Typically, an adaptor implemented in Java adds inbound messages into the Prova engine by using the async protocol. This ensures that the messages for the same conversation-id are processed by the agent on the same thread. This is a specific example of the Mule ESB adaptor that sets the second parameter of the message to "async" and adds the message to the ProvaCommunicator queue.


The following extensive example illustrates how async and task may interoperate in an interesting way. A general assumption is that the reactions belonging to the same conversation run sequentially. However, imagine that while processing a reaction to a message on conversation XID, a rule sends more messages and uses rcvMsg to accept the response. Clearly, if no special care is taken, if another message arrives on the original conversation, it may be processed earlier than the mentioned response arrives, which may in some cases be undesirable. The test msg010.prova shows a particular message-based locking mechanism ensuring that the original messages are processed sequentially. The code uses a Requestor and a Lock Manager to make the messages going via Requestor execute sequentially. Note that since for any XID, the locks are processed on the same thread, they are never in contention and no synchronisation is required. The code of msg010.prova follows.


This is the output from the above example:


Labels: