Apama 10.7.2 | Developing Apama Applications | Developing Apama Applications in EPL | Implementing Parallel Processing | Sending an event to a sequence of contexts
 
Sending an event to a sequence of contexts
In a monitor, you can send an event to a sequence of contexts. The format for doing this is as follows:
send EventExpression to ContextSequenceExpression;
or:
enqueue EventExpression to ContextSequenceExpression;
Note:
The enqueue...to statement will be deprecated in a future release. Use the send...to statement. Both statements perform the same operation.
*Replace EventExpression with any valid EPL expression that is an event. You cannot specify a string representation of an event.
*Replace ContextSequenceExpression with any valid EPL expression that resolves to sequence<context>. You cannot specify a sequence that contains com.apama.Channel objects.
Each statement asynchronously sends a copy of an event to each context in the specified sequence. The event goes to the back of the input queue of each context.
In each target context, the correlator can immediately process the sent event. The correlator does not need to finish executing the action that sent the event (in the source context) before it processes the sent events in the target contexts. The correlator might process a sent event before it finishes executing the action that sent the event. Or, the correlator might process a sent event some time after it completes executing the action that sent the event. The order is unpredictable, depending on the relative execution speeds of the contexts.
The following example uses the sequence type:
action analyse(string symbol) {
   context c1:=context(symbol + "-1");
   context c2:=context(symbol + "-2");
   context c3:=context(symbol + "-3");
 
   spawn submon(symbol) to c1;
   spawn submon(symbol) to c2;
   spawn submon(symbol) to c3;
   sequence <context> ctxs := [ c1, c2, c3 ];
 
   log "Listening for "+symbol;
   on all com.apama.marketdata.Tick(symbol=symbol) as tick {
      send tick to ctxs;
   }
   on com.apama.marketdata.Finished() {
      send com.apama.marketdata.Finished() to ctxs;
   }
}
action submon(string symbol) {
   ...
}
The following example uses the values() method on a dictionary of contexts to obtain a sequence of contexts:
action analyse(string symbol) {
   context c1:=context(symbol + "-1");
   context c2:=context(symbol + "-2");
   context c3:=context(symbol + "-3");
 
   spawn submon(symbol) to c1;
   spawn submon(symbol) to c2;
   spawn submon(symbol) to c3;
 
   dictionary <string, context>
      ctxs := [ "c1": c1, "c2": c2, "c3": c3 ];
 
   log "Listening for "+symbol;
   on all com.apama.marketdata.Tick(symbol=symbol) as tick {
      send tick to ctxs.values();
   }
   on com.apama.marketdata.Finished() {
      send com.apama.marketdata.Finished() to ctxs.values();
   }
}
action submon(string symbol) {
...
}
The send...to and enqueue...to statements do not place the event on the special enqueued events queue. Instead, they put the event on the end of the input queue of each target context. Consequently, it is possible for a send...to or enqueue...to operation to block the sending context from further processing if the input queue of a target context is full. The sending context does not continue beyond a send...to or enqueue...to statement until the event has been placed on the input queues of all target contexts.
If one of the contexts in the sequence does not contain any monitor instances the correlator ignores the sent event in that context because there are no listeners for it.
If one of the contexts in the sequence does not have a valid value before you send an event to it then the correlator terminates the monitor instance.
Consider the following two code fragments:
for c in mySequence {
   send myEvent to c;
}
 
send myEvent to mySequence;
Execution of each of these fragments is typically equivalent. However, you cannot rely on equivalence. When the correlator executes the first fragment, it always delivers the event to the contexts according to their order in the sequence. When the correlator executes the second fragment it can deliver the event to contexts in any order. For example, if a context's input queue is full this can affect the order in which the correlator delivers the event to the contexts.