Parallel processing for instances of an event type
A candidate for implementing parallel processing is when an application performs calculations for a number of events that are of the same type, but that have different identifiers. For example, different stock symbols from a stock market data feed. You can use either of the following strategies to implement parallel processing for this situation:
Create multiple public contexts. Each context listens for one identifier, operates on the events that have that identifier, and discards events that have any other identifier.
Have one context distribute data to multiple contexts, which are each dedicated to processing the events that have a particular identifier.
The performance of these strategies varies according to the work being done. A distributor can be a bottleneck. However, there is a cost in every context discarding events for which it is not interested. In the following situations, the distributor strategy is likely to be more efficient:
There is a very large set of identifiers but a relatively low overall rate of arriving events.
Events must be pre-processed.
Events are not arriving from external sources. Instead, you must explicitly send events.
The sample code below shows the distributor strategy.
event Tick {
string symbol;
integer price;
}
/** In the main context, the following monitor distributes Tick events
to other contexts. There is one context to process each unique symbol. */
monitor TickDistributor {
/** The dictionary maps each unique Tick symbol to the (private)
context that ultimately processes it. */
dictionary<string, context> symbolMapping;
action onload {
Tick t;
on all Tick():t {
// If the context for this symbol does not yet exist, create it.
if(not symbolMapping.hasKey(t.symbol)) then {
context c := context("Processing-"+t.symbol);
symbolMapping[t.symbol] := c;
spawn processSymbol(t.symbol) to c;
}
// Send each Tick event to the context that handles its symbol.
send t to symbolMapping[t.symbol];
}
}
/** The following action handles Tick events with the given symbol.
This action executes in a private context that processes all Tick
events that have one particular symbol. */
action processSymbol(string symbol) {
Tick t;
// Because this context receives a homogeneous stream of Tick events
// that all have the same particular symbol, there is no need to specify
// an event listener that discriminates based on symbol.
on all Tick():t {
...
}
}
}