Functional listeners
Fn provides some actions which interact with events and listeners. These allow you to use a functional style of code to also listen for events.
Example of how you might use these where you might have wanted to write:
on all Event(f="val1") as e or all Event(f="val2") as e or ... { eventArrived(e); }
However, you have a variable number of possible values, and they are not in a contiguous range. With Fn, you can write:
sequence<listeners> ls := Fn.listenForAnyOf(["val1", "val2"], "com.apamax.samples.Event", "f", {}, eventArrived);
on Stop() {
any _ := Fn.map(ls, Fn.partial(callAction, "quit", []));
}
Another common pattern is having an asynchronous process with a completed event. You have a similar issue listening to a variable number of processes. With the functional API, you can now write this:
on Completed(id=1) and Completed(id=2) and ... and not wait(TIMEOUTSECS) { onCompleted(); }
on wait(TIMEOUTSECS) and not (on Completed(id=1) and Completed(id=2) and ... ) { onTimeout(); }
as:
Functional(sequenceIDs).waitForAllCompleted("Completed", "id", onCompleted).onTimeout(TIMEOUTSECS, onTimeout);
Lastly, we want to receive all events up until a termination condition and then process them as a collection. Rather than accumulating them all in a container manually with multiple listeners like this:
sequence<ValueEventName> vals := new sequence<ValueEventName>;
on all ValueEventName(fields=valueEventFields) as v
and not EndEventName(fields=endEventFields) or wait(timeout) { vals.append(v); }
on EndEventName(fields=endEventFields) and not wait(timeout) { onComplete(vals); }
on wait(timeout) and not EndEventName(fields=endEventFields) { onTimeout(vals); }
You can write this instead:
Functional.getAllEvents("ValueEventName", {...}, "EndEventName", {...}, onComplete).onTimeout(TIMEOUTSECS, onTimeout);
The following table lists the event and listener actions on Fn.
Action | Description | Arguments | Returns |
waitForAllCompleted | Listens for events with a field matching every value from a functional sequence, and calls a completion action when all have arrived (similar to an EPL and event expression). | Sequence of values. Event type name. Field name. Timeout. action<> on success. | sequence<listener> |
getAllEvents | Listens for events matching the specified fields, and then calls an action with the received events once a terminating event arrives. | Event type name. Dictionary of event fields. Event type name. Dictionary of event fields. action<sequence<EventType>> on success. | sequence<listener> |
listenForAnyOf | Listens for events with a field matching any value from a given sequence, and calls an action when each one arrives (similar to an EPL or event expression). | Sequence of values. Event type name. Field name. Additional fields. action<Eventtype> | sequence<listener> |
onTimeout | Waits for a given timeout and then if any of the specified listeners are still valid, quits them and calls an action. | sequence<listener> action<> on timeout. | nothing |