How can I have multiple contexts handle events in Apama

131 views Asked by At

I am trying to define a monitor in which I receieve events and then handle them on multiple contexts (roughly equating to threads if I understand correctly) I know I can write

spawn myAction() to myNewContext; 

and this will run that action in the new context.

However I want to have an action which will respond to an event when it comes into my monitor:

on all trigger() as t {
  doMyThing()
}

on all otherTrigger() as ot {
  doMyOtherThing()
}

Can I define my on all in a way that uses a specific context? Something like

on all trigger() as t in myContext {
  doMyThing()
}

on all otherTrigger() as t in myOtherContext {
  doMyOtherThing()
}

If not what is the best way to define this in Apama EPL? Also could I have multiple contexts handling the same events when they arrive, round robin style?

2

There are 2 answers

0
Madden On BEST ANSWER

Apama events from external receivers (ie the outside world) are delivered only to public contexts, including the 'main' context. So depending on your architecture, you can either spawn your action to a public context

// set the receivesInput parameter to true to make this context public
spawn myAction() to context("myContext", true);

...

action myAction() {
    on all trigger() as t {
        doMyThing();
    }
}

or, spawn your action to a private context and set up an event forwarder in a public context, usually the main context (which will always exist)

spawn myAction() to context("myNewContext");
on all trigger() as t {
    send t to "myChannel"; // forward all trigger events to the "myChannel" channel
}

...

action myAction() {
    monitor.subscribe("myChannel"); // receive all events delivered to the "myChannel" channel
    on all trigger() as t {
        doMyThing();
    }
}

Spawning to a private context and leveraging the channels system is generally the better design as it only sends events to contexts that care about them

2
HenryLockwood On

To extend a bit on Madden's answer (I don't have enough rep to comment yet), the private context and forwarders is also the only way to achieve true round-robin: otherwise all contexts will receive all events. The easiest approach is to use a partitioning strategy (e.g. IDs ending in 0 go to context-0, or you have one context per machine you're monitoring, etc.), because then each concern is tracked in the same context and you don't have to share state.

Also could I have multiple contexts handling the same events when they arrive, round robin style?

This isn't entirely clear to me. What benefit are you aiming for here? If you're looking to reduce latency by having the "next available" context pick up the event, this probably isn't the right way to achieve it - the deciding which context processes the event means you'd need inter-context communications and coordination, which will increase latency. If you want multiple contexts to process the same events (e.g. one context runs your temperature spike rule, and another runs your long-term temperature average rule, but both take temperature readings as inputs), then that's a good approach but it's not what I'd have called round-robin.