October 10, 2017
by Dmitri Zimine
In Part 1 of the series, I shared my excitement with two new event-driven systems introduced last month: Event Grid from Microsoft Azure and Event Gateway from Serverless.com, and posted some observations on Event Grid.
Before we continue with Event Gateway, let’s bring the “terminology normalization” from Part 1. In the table below StackStorm terms are used as as a reference point for our blog’s regular readers, along with a short explanation of their meaning for the guests.
|StackStorm||Event Grid||Event Gateway||What is it|
|Sensors||Event publishers||N/A (out of scope)||Event sources and a system responsible for ingesting external events|
|Triggers||Topics||Events||System representation of the external event|
|Rules||Subscriptions||Subscriptions||Triggers-to-Actions map, filtering, conditions, data passing|
|Actions||Event Handlers||Function||Target system invocation|
If you’re new to StackStorm, you can refresh refresh the concept of event driven automation at StackStorm documentation.
The common questions to evaluate the event automation products in the family would be:
And of course there is something uniquely interesting in each system. What is it?
With that, let’s continue to Event Gateway!
Event Gateway is defined as “an open-source communication fabric for serverless architectures. It combines both API gateway and pub/sub functionality into a single experience”[*].
The “pub/sub” part is what makes Event Gateway an event router, similar to Azure Event Grid. Event Gateway is emphasized as “Cross-cloud”, built to centralize event handling and react to event with any function on any cloud. This positioning reflects anticipation that serverless solutions are going to be spanning multiple cloud providers.
The “API gateway” part is a separate functionality, yet a part of the end-to-end developer experience: it is intended to optimize the synchronous calls to Function-as-a-Service functions of various cloud providers – think of AWS API Gateway functionality across the cloud, without dealing with notoriously painful AWS API gateway configuration.
As a service offering by Serverless.com, Event Gateway is tightly integrated into the serverless framework for a seamless developer experience. How tightly & how seamlessly? Austen Collins demo-ed it at Emit conference and the flow was impressive – watch the video once they post it, and judge for yourself. (I’ll update the post with the link once the video is posted). Or just try yourself – it is open-source: open for contributions, transparent for understanding, and can be run by anyone in their own production cluster. The transparency makes this review an easy job – look at the code, run the example, and let’s compare notes!
Event sources are outside of Event Gateway’s scope: the platform doesn’t offers anything like StackStorm sensors – a way to plug-in a piece of code to sense an external event. Instead, EventGrid ingests events via HTTP(s) endpoint. A custom event is most similar to StackStorm WebHook trigger type or EventGrid custom topic. When emitted, triggers an asynchronous call to one or more target functions based on subscriptions.
Events identify themselves by a string ID passed in via HTTP header. Namespacing is not enforced but will likely emerge as a convention. Event payload comes in a HTTP request body and parsed by EventGrid if it is JSON. As event types are not registered upfront, thus there is no payload schema, no static check, and no introspection on which payload parameters may be available for subscription filtering. Well, unfortunately there is no filtering either – I’ll get to it when it comes to subscriptions.
There are also two “built-in” synchronous event types, essential for “just call me” use cases like using functions as client application backends, and function calls across cloud providers (I think of them as part of Event Grid’s API Gateway functionality):
invokeevent type is used to call functions synchronously. It does not require a subscription: using
invokeis like calling StackStorm Action API directly instead of going through the Trigger-Rule-Action chain. The function invocation output is sent in the response body “as is”.
httpevent occurs on HTTP requests on the Gateway paths defined by a special
httpsubscription type. The event carries
querystring, headers and the other parameters of HTTP call to the function defined by the subscription. The function execution results are synchronously sent back to the caller in HTTP response
There is also an internal event types. StackStorm users know how powerful internal triggers like
st2.generic.actiontrigger can be in building elaborate chains of event reactions. In EventGrid, a few system events are defined –
with intention to add more.Here is an example of using
internalFunctionError for error handling. To realize their potential, the system events must become first class citizens, useful in subscriptions, with extra safeguards and usability aids to track the chains of events, break circular dependencies and prevent invocation chain reaction explosions.
Functions must be pre-registered via configuration API. This is referred as “Function discovery”: it stores information about available functions, allowing the Event Gateway to call them as a reaction to received event. The three function types available today: AWS Lambda, HTTP, and Weighted. Weighted is an interesting concept: the call is load-balanced across a set of functions with probabilities based on each function’s user-assigned “weight”. There will be more function types: the docs already cite Google Cloud Functions, Azure Functions, OpenWhisk Actions. Function providers are not pluggable in the current implementation – adding a new function type to Event Gateway requires modification of the platform code – but it will likely change as more types are implemented. I am particularly looking forward to invoking Step Functions and Logic Apps as the workflows will be used more to tame serverless complexity – and adding support for them looks pretty easy.
Subscriptions map events to functions. Created via the same configuration API, subscriptions are as simple as Event Gateway’s, even simpler: just
(functionID, event)` tuple. It does no filtering on event, and doesn’t offer any data transformation from event payload to function input, passing event payload to function as is. The lack of filtering pushes part of event routing responsibility onto functions: users will have to either mix routing and domain logics in function, or front-face the handlers by a “routing” function. The lack of data transformation creates data coupling between events and functions. This is unfortunate: the promise of Event Gateway is that it “completely decouples functions from one another, reducing communication costs across teams, eliminates effort spent redeploying functions, and allows you to easily share events across functions, HTTP services, even different cloud providers”, and in it current form, it’s not “completely decoupled”. However event filtering is already on the roadmap and well thought out. Data transformation is not yet in the plans, but from our experience with StackStorm it will be necessary.
A special HTTP subscription is used to define an HTTP API endpoints by mapping paths and methods to synchronous function calls. HTTP subscription is created when the event type is
http, and takes
method parameters. There can be only one http subscription for the same
(method, path) pair. It was not easy to get my head around special case for
http at first, but now I find it easy to think about it as API Gateway functionality, and it is a very convenient way to expose functions as REST endpoints.
Event Gateway is a horizontally scalable stateless service. It relies on strongly consistent DB (etcd, Consul, Zookeeper) for managing state and inter-cluster communications. A cluster can span multiple cloud regions or even various cloud providers.
Delivery guarantee is not specified; from looking at the code I would guess “at most once” but happy to be corrected. Retry is left to the event emitting clients for the time and cited as a feature request.
What makes Event Gateway really appealing is the convenience of integration with Serverless framework. User describes the event-action mapping with already familiar syntax in
serverless.yml, and the framework makes all the calls to register a function & create a subscription:
functions: analytics: handler: recordEvents events: - user.registered - user.clicked
Here is how the end-to-end developer experience is promising to be, once the Event Gateway is out in production:
httpevents for client app backend services,
invokeevents to synchronously call functions from functions, and custom async events for orchestrating backend jobs.
sls deploy, the functions will be deployed to the cloud providers, registered in Event Gateway via functional discovery, and event subscriptions will be created.
Event Gateway is currently in beta, and under active development (the development noticeably slowed down since it’s peak in August, which, I must admit, concerns me). While AWS, Azure, Google GCP & IBM OpenWhisk are mentioned in docs, only AWS is implemented at the time of writing. The hosted service is not available yet: one can run Event Gateway locally via Serverless framework, or standalone.
Event Gateway is hardly useful at the current early preview stage, but looks very promising on its roadmap. A cross-cloud event router is “the missing piece of serverless architectures”[*], and Event Gateway makes a strong claim to this strategic spot. The combination of pub/sub and API gateway functionality provides single developer experience – the majority of solutions need both types of interactions. In addition, Event Gateway promises to serve as an “event store” – keep events long after execution to enable event-sourcing. Open-source model brings trust and carries the potential of a strong community support. I am looking forward to seeing Event Gateway develop towards achieving its grand vision.