The event
library provides functions for understanding an event and the environment in which it was raised as well as actions for sending events.
Event Functions
There are three categories of event functions.
Event Environment
For historical reasons, some of these are Web-centric. The following functions are available:
event:env()-
returns information about the event's environment. The function takes an argument that determines what will be returned:
caller -
return the URL of the Web page on which the event is firing (assumes an event in theweb
domain)ip -
return the IP number of the endpoint (client).referer -
return the URL of the referring page to the caller (assumes a web event).title -
return the page title of the calling page.- txn_id - return the transaction ID of this ruleset evaluation.
Event Attributes
event:attr() -
returns a specific event attribute. The function takes the name of the attribute to be returned as its sole argument.event:attrs() -
returns all the event attributes as a map.
Event Channels
event:channel()
- returns information about the event channel. The function takes an argument that determines what is returned:id
- returns the event channel identifier.
Event Actions
The event library supports sending events to event channels.
event:send(<subscription_map>, <domain>, <type>)
The <domain>
and <type>
are expressions that evaluate to strings. These arguments are optional. If they are not present, the values with keys _domain
and _type
from the subscription map will be used.
A subscription map is any map that contains an event channel identifier (identified by the key cid
) or an event signal URL (identified by the key esl
). The other key-value pairs in the map are optional. The following code sample shows a subscription map:
subscription_map = {"name":"Phil", "phone":"8013625611", "cid":"072a3730-2f8a-052f-2ddb-00553e411455", "calendar":"https://www.google.com/calendar/..." };
Given the preceding subscription map declaration, we could send a notification:status
event to the event channel identified by the CID in the map as follows:
event:send(subscription_map, "notification", "status")
If the subscription map contains both a CID and an ESL, the ESL is used to send the event.
Event attributes can be specified in the optional action parameter attrs
. To send a notification:status
event with the attributes priority and subject, we would modify the preceding example as follows:
event:send(subscription_map, "notification", "status") with attrs = {"priority": "2", "subject" : "urgent message" }
Of course, the arguments and parameters of an action can be calculated.
If the ESL or CID have non-standard keys in the subscription map, you can use the parameters cid_key
or esl_key
to give the key name:
event:send(subscription_map, "notification", "status") with attrs = {"priority": "2", "subject" : "urgent message" } and cid_key = "channel_id" event:send(subscription_map, "notification", "status") with attrs = {"priority": "2", "subject" : "urgent message" } and esl_key = "event_url"
Results
In general, you shouldn't be relying on results from sending an event. Rather, the recommended pattern is to have the receiving event network communicate by sending an event to the original sender. However, it is often useful to know whether or not the send()
succeeded. To support this, the system will raise a system:send_complete
event when all threads have completed. The event has a single attribute called send_results
that contains an array of the results of the individual sends. Each member of the array has the following structure:
{"esl" : <esl>, "result" : {"status" : <http status code>, "reason" : <http reason>, "body" : <http body> } }
You can use a rule like the following listen for the system event and loop over the results:
rule catch_complete { select when system send_complete foreach event:attr('send_results').pick("\$..status") setting (status) notify("Status", "Send status is " + status); }
Obviously, you probably don't want to merely print the status out, but rather check it and do something if it is not 200.
Patterns
A common pattern when sending events is to loop over the subscribers and then raise an explicit event when done. The on final guard condition is used to ensure the explicit event is only raised once.
rule dispatch { select when explicit schedule_inquiry foreach subscribers setting (subscriber) pre { resp_cookie = math:random(99); } event:send(subscriber,"schedule","inquiry") with attrs = {"from" : event:attr("From"), "message": event:attr("Body"), "cookie": resp_cookie }; } always { raise explicit event subscribers_notified on final } }
The difference between raising an explicit event on final
and using the system generated system:send_complete
event shown above might not be obvious.
The primary difference is that the explicit event does have access to result information, including status. But, both the explicit event shown in the preceding code and the system:send_complete
event will cause any rules that are selected based on the respective events to be scheduled. Similarly neither will cause rules to be run before send()
is complete since parallel send()
actions must all complete before the rule they are in can complete.
Additional Information
The blog post Federating Personal Clouds shows an example using send()
.