This
is my second installment on a series devoted to the Apama
Event Processing Language, MonitorScript. In my introduction
to the Apama EPL I described the basic structure of the language, some
concepts and terminology. I also included the obligatory Hello World sample.
In this entry I'll continue that basic tutorial delving
into the elemental structure of
the EPL. I've decided to do this to highlight the very simple fact that
the language adheres to the principles of structured programming.
Just so we're all on the same page, here's a definition I
found
on the web:
That's a definition that is clearly irrefutable. In order for a language to live up to that definition it must have a number fundamentals. Code modularity, or developing code as separate modules. This allows for parallel development, improves maintainability and allows modules to be plug replaceable. Encapsulation is a means of hiding an implementation or inner workings of a calculation or algorithm. Lastly there are Interfaces and instances. This architectural pattern may be applied to the design and implementation of applications which transmit events between loosely coupled software components. These are just a few of those fundamentals. These essential elements of languages have been part of the scene for decades. They are present in the procedural programming languages like C and in object oriented languages like C++ and java.
Lest we forget our roots as software engineers, with all the hype surrounding CEP and their constituent domain-specific languages, it's important to do a reality-check and not get swept up and forget the basic principles necessary for creating long-standing maintainable code. Last year I wrote a piece on readability as a criteria for a successful language this is primarily based on a development language having these basic fundamentals: modularity, encapsulation, interfaces and instances.
Apama's EPL, MonitorScript has all these capabilities, as I will describe below. It's what allows us to build reusable framework components, and solutions. Which we've done so with our Capital Markets Framework and Solution Accelerators for FX Aggregation, Smart Order Routing, Surveillance, Bond Pricing, etc. These are components written in our EPL that have the plug'n'play modularity to be redeployed in multiple customers.
To illustrate this idea of structure - modularity, encapsulation and interfaces I'll use a short example of a producer and consumer. This is a common design pattern or idiom we use extensively. The Apama EPL's event paradigm extends not only to the type of CEP applications we enable but also to the nature of the language itself. If you're familiar with message passing languages such as Erlang this will be a familiar concept. Different modules that make up an application communicate with one another by passing messages (or events as is the case).
In this example I have a service or producer monitor that generates and sends Item events, a client or consumer monitor that consumes Item events and an interface for the interaction between the two. If the term Monitor seems strange, I've defined a set of terms and concepts in my introduction, I suggest a quick review of that get up to speed.
The interface to the monitor, defined below is the set of events it receives and transmits. The event definitions for these events are declared within a package name (i.e. com.apamax.sample). Apama's EPL supports java-like package names for name-space isolation to strengthen that modularity notion.
The Item Interface.
package com.apamax.sample;
event SubscribeToItems { event UnsubscribeFromItems { event Item { |
The Item Interface is simply a set of prescribed events. Two are to instruct the consumer to start/stop receiving Items and the Item definition itself. As I mentioned it uses a subscription idiom. We use this notion extensively where a Monitor is a layer over some subscription-based service such as a market data adapter. A real market data interface would be much more extensive. Here, I've scaled it back for the sake of simplicity, but you can imagine a more robust interface including error handling and status events.
package com.apamax.sample;
monitor ItemClient { SubscribeToItems subscribeToItems;
on all Item():item { |
The Item consumer is also a Monitor in the com.apamax.sample namespace. It is a user of our event interface to the Item service and as such is interested in receiving events of type Item. The interface defines the means to do this by subscribing. The consumer simply has to create a SubscribeToItems event and forward it to producer service.
As I mentioned earlier, the Apama EPL adheres to an event paradigm as a fundamental characteristic of the language. The route statement is a means by which Monitors communicate. This is another precept and underlines the fundamentals of modularity and encapsulation.
Once a subscription request has been sent (route subscribeToItems), the consumer listens for Items events, (on all Item()). In this simple example, we're just looking to receive them all without any filtering or pattern matching. I will explore event pattern matching - both the simple and complex in a follow-up blog.
To complete the picture, the sample tests a field in the Item event and terminates the subscription if it exceeds a constant value, (item_count > 10).
package com.apamax.sample;
monitor ItemService { on all SubscribeToItems():subItems { on all UnsubscribeFromItems():unsubItems { action startItems(string name) { |
The Item producer is also in the com.apamax.sample namespace. It defines listeners for SubscribeToItems and UnsubscribeFromItems.Two events from our interface. Typically, subscriptions would be managed on a per-user basis, thus allowing multiple consumers to subscribe to our Item service. This is a detail I will outline in a subsequent installment along with a few other related features such as instance management.
Once a subscription request has been received, the startItems action (i.e. a method) is invoked to continuously route Item events to the consumer every 0.1 seconds (on all wait(0.1) ...) . Again, in a real world scenario, this particular portion of a service would be more involved, such as possibly managing the interaction to an external adapter for example.
For terminating a subscription on behalf of the client (on all unSubscribeItems()), we simply terminate the wait listener (a looping construct) set up in startItems.
In future installments on the Apama EPL, I'll delve into a few more of the language constructs that extend this basic idiom (multiple consumers, spawning, and parallelism).
Once again thanks for reading,
Louie
View all posts from The Progress Team on the Progress blog. Connect with us about all things application development and deployment, data integration and digital business.
Let our experts teach you how to use Sitefinity's best-in-class features to deliver compelling digital experiences.
Learn MoreSubscribe to get all the news, info and tutorials you need to build better business apps and sites