Skip to end of metadata
Go to start of metadata
Reaction group instance creation

Each reaction group is a template from which group instances are created each time, during the evaluation of the current goal, the engine encounters an event channel with a new conversation-id XID. The fact that there may exist another group instance for the same XID is irrelevant, what does matter is that during the processing of the current goal, this XID was encountered for the first time.

Reaction group instance initialisation

Once a group instance is created, the engine creates a hidden temporal reaction with current free and bound variables and then executes a Prolog fail on each event channel (rcvMsg or rcvMult) annotated with the same group identifier GID using @group(GID). This fail continues the standard non-deterministic goal evaluation so that the engine visits other branches possibly containing more event channels or the exit channel for the same group. When the engine visits the exit channel, the group instance is assigned its type according to the associated annotation, @and or @or, which completes its initialisation. The initialised group instance then intercepts all events that match any of the created temporal reactions.

How many group instances can co-exist?

It is important to appreciate that there may exist quite a few active group instances at the same time. The number of active group instances is only limited by process memory and, of course, the CPU power of the machine so that it can perform matching against all existing instances for any inbound event, the task simplified by partitioning on conversation-id for any messages on the async protocol (that is always recommended for use in event processing in Prova), as well as by indexing of head literals.

What are the conditions for the group instance termination?

Setting aside the efficiency, a more important question is 'when do the group instances terminate?' A typical reaction group terminates whenever the event pattern that it defines is detected, or a timeout occurs. The matter becomes, of course, more complicated if detection multiplicity or recurring pattern emission are part of the group definition. For examples, the @vars annotation results in continuous joins between the equivalently named variables in different channels, so that event if one tuple is detected, the group instance does not terminate until the group is terminated in some other way, for example, by the group timeout or when a control channel stops one or more channel or the whole group instance.

Group instance extension (using an infinite reaction group example)

However, there exists a way for the group instance to be "extended" by one or more new reaction, even if it already is about to be terminated, either successfully or unsuccessfully.

Consider the following complete, fairly interesting example, rules/reloaded/stable_limit.prova.

The code contains a test driver client that sends events to a server that, interestingly, contains a self-recursive clause server_2. The test looks for the occurrences of the following sequential pattern:

  1. The price is above the Limit.
  2. The price is below the Limit.
  3. The price stays below the Limit for at least a specified interval of time.

Now, a lot of things can go wrong here.

  1. We have to make sure that a new detection does not start each time the updated price is still above Limit.
  2. We have to make sure that we restart detection if the price goes back up too soon, before the specified interval of time expires.

The first server_1 clause guarantees the first requirement. As rcvMsg is used here with multiplicity one, only the very first price update with price>Limit will start the detection. Does not this then contradict the second requirement? No, because of the second reaction in the server_2 clause.

This reaction is annotated with both @not and @timeout. If the matching event (price above Limit) arrives before the timeout, the AND group should have been normally terminated. However, due to recursion to the first reaction in server_2 again, the reaction group life is extended so that the wait begins for the price to dip down again under Limit.

When a group instance gets extended?

IF

  1. a reaction group instance receives a matching event in one of its group channels
  2. AND the conditions are met for the group instance to either successfully detect an event pattern or be unsuccessfully terminated
  3. AND the evaluation of the continuation subgoal encounters reaction(s) for the same logical group and conversation-id

THEN

  1. the group completion or termination is canceled,
  2. one or more new temporal reactions are created and initialised as part of this group instance,
  3. the lifetime of the reaction group instance is thereby extended.

In the above example, the group instance for logical group g1 and conversation-id Market is extended in the self-recursive clause server_2 and will continue looking for the time interval when the price stays low continuously.

Labels: