EventJava - Purdue University

27
EventJava * P. Eugster and K.R. Jayaram Department of Computer Science, Purdue University, West Lafayette, IN 47906 {peugster, jayaram}@cs.purdue.edu Abstract Event correlation has become the cornerstone of many reactive applications, particularly in distributed systems. However, support for programming with complex events is still rather specific and rudimentary. This paper presents EventJava, an extension of Java with generic support for event-based distributed programming. EventJava seamlessly integrates events with methods, and broadcasting with unicast- ing of events; it supports reactions to combinations of events, and predicates guarding those reactions. EventJava is implemented as a framework to allow for customization of event semantics, matching, and dispatching. We present its implementation, based on a compiler transforming specific primitives to Java, along with a reference implementation of the framework classes. We discuss ordering properties of EventJava through a formalization of its core as an extension of Featherweight Java. In a perfor- mance evaluation we show that EventJava compares favorably to a highly tuned database-backed event correlation engine as well as to a comparably lightweight concurrency mechanism. Contents 1 Introduction 2 2 EventJava by Example 3 2.1 Event Methods ............................................ 3 2.1.1 Handling events ....................................... 3 2.1.2 Unicast ............................................ 4 2.1.3 Broadcast ........................................... 4 2.2 Complex Events and Correlation Patterns ............................. 4 2.3 Streams ................................................ 4 2.4 Matching Semantics ......................................... 5 2.5 Context ................................................ 5 3 EventJava Syntax and Semantics 6 3.1 Featherweight EventJava (FEJ) Syntax .............................. 6 3.2 FEJ Definitions ............................................ 7 3.3 Typing ................................................. 7 3.3.1 Integration with Java RMI ................................. 8 3.3.2 Constraints on event methods ................................ 8 3.3.3 Overriding .......................................... 9 3.4 Evaluation ............................................... 9 3.5 Soundness ............................................... 10 * Financially supported by National Science Foundation (NSF) through grants number 0644013 and number 0834529. 1

Transcript of EventJava - Purdue University

Page 1: EventJava - Purdue University

EventJava∗

P. Eugster and K.R. JayaramDepartment of Computer Science, Purdue University, West Lafayette, IN 47906

{peugster, jayaram}@cs.purdue.edu

Abstract

Event correlation has become the cornerstone of many reactive applications, particularly in distributedsystems. However, support for programming with complex events is still rather specific and rudimentary.This paper presents EventJava, an extension of Java with generic support for event-based distributedprogramming. EventJava seamlessly integrates events with methods, and broadcasting with unicast-ing of events; it supports reactions to combinations of events, and predicates guarding those reactions.EventJava is implemented as a framework to allow for customization of event semantics, matching, anddispatching. We present its implementation, based on a compiler transforming specific primitives toJava, along with a reference implementation of the framework classes. We discuss ordering propertiesof EventJava through a formalization of its core as an extension of Featherweight Java. In a perfor-mance evaluation we show that EventJava compares favorably to a highly tuned database-backed eventcorrelation engine as well as to a comparably lightweight concurrency mechanism.

Contents

1 Introduction 2

2 EventJava by Example 32.1 Event Methods . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3

2.1.1 Handling events . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32.1.2 Unicast . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42.1.3 Broadcast . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4

2.2 Complex Events and Correlation Patterns . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42.3 Streams . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42.4 Matching Semantics . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52.5 Context . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5

3 EventJava Syntax and Semantics 63.1 Featherweight EventJava (FEJ) Syntax . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63.2 FEJ Definitions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 73.3 Typing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7

3.3.1 Integration with Java RMI . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 83.3.2 Constraints on event methods . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 83.3.3 Overriding . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9

3.4 Evaluation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 93.5 Soundness . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10

∗Financially supported by National Science Foundation (NSF) through grants number 0644013 and number 0834529.

1

Page 2: EventJava - Purdue University

4 Implementation 114.1 Implementation Framework . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12

4.1.1 Framework components . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 124.1.2 Code transformations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12

4.2 Deterministic Matching in the Jess Reference Implementation . . . . . . . . . . . . . . . . . . 124.2.1 Rete-based matching . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 134.2.2 Semantics . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 134.2.3 Ordering properties . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13

5 Translating EventJava to Java 145.1 Transformations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14

5.1.1 Sink side . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 145.1.2 Source side . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15

5.2 Helper Classes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 155.2.1 Broadcast classes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 155.2.2 Resolver . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16

5.3 Substrate . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16

6 Evaluation 186.1 Cayuga . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 186.2 Complexity of Correlation Patterns . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 186.3 Cω . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 196.4 EventJava Latency . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19

7 Discussion 207.1 Broadcast vs Multicast . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 207.2 Bootstrapping and Groups . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 207.3 Order . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 207.4 Garbage Collection . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 207.5 Return Values . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21

8 Related Work 218.1 Concurrency . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 218.2 Publish/subscribe, Streams, and Flows . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 228.3 Aspects . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22

9 Conclusions and Outlook 22

10 Acknowledgements 23

2

Page 3: EventJava - Purdue University

1 Introduction

Events demark incidents in the execution of software, a change of state in some component. In a distributedevent-based system (DEBS), software components communicate by transmitting and receiving event notifi-cations, which reify the event and describe the observed state change. Some examples of events in differentdomains are (i) the reading from a temperature sensor, (ii) a stock quote, (iii) a link failure in a networkmonitoring system, (iv) change of relationship status in a social networking tool, or (v) drop in inventory be-low a defined threshold. Interacting objects in a DEBS can act in two roles, namely as (a) sources (notifyingevents), and as (b) sinks (manifesting interest in being notified of events). Objects may act as both sourcesand sinks. Event notifications describe state changes by attributes attached to them. Explicit attributesrepresent application-specific data, for example, a stock quote event has the name of the organization, theprice of the stock and the opening price as explicit attributes. These are sometimes paired with implicitattributes conveying contextual information, such as wall clock time, logical time, geographical/logical co-ordinates, or sources. Henceforth, we will use the term events to refer to both the incidents underlying suchevents as well as to their incarnations/notifications.

Sinks are not always interested in single events. Events can be correlated with other events, resulting incomplex events. Examples are:1

• Average of temperature readings from 10 sensors inside a boiler (aggregation).

• Average of temperature readings from a sensor within a 10 minute interval (aggregation + temporalcorrelation).

• The price of a stock decreases for 10 successive stock quotes immediately after a negative analyst report(sequencing and temporal correlation).

• Two insider trades of a large volume (≥ 10000) immediately after a stock price hits its 52 week high(sequencing and temporal correlation).

• Release of a new LCD TV by Samsung followed by 5 positive reviews in 1 month (sequencing andtemporal correlation).

Event correlation is widely used in algorithmic trading and financial services, patient flow monitoringin hospitals, routing and crew scheduling in transportation, monitoring service level agreements in call cen-ters, consumer behavior in on-line retailing and airline baggage handling, network monitoring and intrusiondetection [1], active databases [2] just to name a few. In pervasive computing, events are often viewed asan adequate interaction abstraction due to their strongly asynchronous nature [3]. Examples of specializedevent correlators in the database community are Cayuga [4], Aurora [5], or Borealis [6].

In DEBS, interacting objects (sources, sinks) typically form groups. For example, the object that publishesstock quotes and objects which monitor stocks (at several stock brokers) are in a group – managed eitherusing a group communication system (e.g. Spread [7]) or a specialized event dissemination middleware(e.g. Hermes [8]). Objects in DEBS thus commonly interact in one-to-many (multicast) style. Sourcesand sinks do not need to know the identities of each other, as sources publish events to the group, whichwhich delivers them to sinks. Besides group membership, fault tolerance is usually also provided by themiddleware. Consequently, components in DEBS are asynchronous, decoupled and the interaction betweenthem is usually anonymous.

In support of an increasing family of programs based on events and event-correlation in particular, wepropose in this paper a novel extension of the mainstream Java programming language, called EventJava.This paper presents its design, semantics and implementation, starting by an illustration its features throughexamples. The technical contributions of EventJava and this paper are:

1www.thecepblog.com, www.complexevents.com, www.event-based.org

3

Page 4: EventJava - Purdue University

1. A programming model with generic support for event-based interaction merged with objects. Thismodel is implemented as an extension to Java, EventJava, incorporating features for flexible eventcomposition (aggregation, temporal correlation, streams), and broadcast and unicast of events.

2. An implementation framework for event correlation promoting flexible propagation and matching ofevents. A reference implementation of this framework is presented, based on the Rete pattern matchingalgorithm [9] in the Jess expert system shell [10], and the JGroups [11] group communication system.Empirical evaluation shows that these custom off-the-shelf components can be used to achieve perfor-mance and scalability comparable to highly specialized correlation engines or lightweight concurrencymechanisms, illustrating the adequacy of the abstractions proposed in EventJava.

3. Formal semantics of event correlation in EventJava expressed as an extension to Featherweight Java(FJ) [12].We also present precise semantics for event correlation in our reference implementation, showing thatit preserves the ordering of events of the middleware layer.

The remainder of this paper is organized as follows. Section 2 presents EventJava through examples. Sec-tion 3 details its syntax and semantics. Section 4 presents an implementation of EventJava based on aframework for semantics customization. Section 7 discusses various design and implementation issues. Sec-tion 6 evaluates the performance of EventJava. Section 8 presents related work. Section 9 draws conclusions.For comparison purposes, Appendix A outlines an implementation in Java of an example presented in Sec-tion 2.

2 EventJava by Example

This section gives an overview of EventJava, introducing its features stepwise through simplified examples.

2.1 Event Methods

An application event type is implicitly defined by declaring an event method, a special kind of asynchronousmethod. The formal arguments of event methods correspond to the explicit attributes of the event type.

2.1.1 Handling events

Consider the example below of a travel agency which notifies its customers of severe weather in cities thatare part of their flight itineraries. Instances of the Alerts class react to simple severeWeather events byretrieving the email addresses of flight passengers (in- or outbound for the city) from a database and sendingemails to them. Sinks can specify additional constraints on event attributes through predicates, which followthe when keyword.class Alerts {

ItineraryDatabase db;event severeWeather(String city, String description, String source)when (source == "weather.com") {

Iterator<Itinerary> it = db.getItinerariesByCity(city).iterator();while(it.hasNext()} { Messenger.sendEmail(it.getAssociatedEmail());}

}}

In this example, the travel agency only trusts alerts from weather.com. The method body is called areaction and is executed asynchronously in a separate thread upon occurrence of the event satisfying thepredicate. Arguments are considered to be values, i.e., of primitive types or conforming to Serializable, toenable event notification across address spaces.

4

Page 5: EventJava - Purdue University

2.1.2 Unicast

An event can be notified to a single destination object simply by invoking the corresponding event methodon that object. To that end, the source object needs a reference to the sink – a stub if the sink is remote.For example, a severeWeather event can be notified to an instance a of Alerts as follows:a.severeWeather("Chicago", "Snow Storm 15 inches","weather.com");

2.1.3 Broadcast

The same severeWeather event can be notified to all instances of Alerts just like a static method call:Alerts.severeWeather("Chicago", "Snow Storm 15 inches","weather.com");

When an event method e() is invoked on a class C it is broadcast to all live instances of C and all instancesof any subclass C ′ of C. By all instances of a class C, we mean all local instances and all remote instances ofC within the group (see Section 4 on remote interaction and bootstrapping). When the invocation happenson an interface I, the event is broadcast to all instances of all classes C implementing I.

2.2 Complex Events and Correlation Patterns

Complex events are defined by correlation patterns, comma-separated lists of event method headers, e.g.e1(),e2(),...,eq() , preceded by event, (cf. Cω[13]). As we will detail later, the correlation semantics canbe sensitive to order.

Consider an algorithmic trading example comparing earningsReport and analystDowngrade events. If astock has a negative earnings report (the actual earnings per share, epsAct, is less than the estimate epsEst),followed by an analyst downgrade to “Hold”, then the algorithm recommends selling the stock.class StockMonitor {

Portfolio p;event earningsReport(String firm, float epsEst, float epsAct, String period),

analystDowngrade(String firm1, String analyst, String from, String to)when ( earningsReport < analystDowngrade &&firm == firm1&& epsAct < epsEst && to == "Hold") {p.RecommendSell(firm);

}}

The first condition earningsReport < analystDowngrade compares an event earningsReport with a subse-quent analystDowngrade event. It is a shorthand notation for earningsReport.time < analystDowngrade.time.The time attribute is a default implicit event attribute representing timestamps for events (explained shortly).Similarly, firm could have been used in lieu of firm1 in analystDowngrade, and earningsReport.firm andearningsReport.firm could have been used in the predicate and reaction for disambiguation.

As a comparison, Figure 18 in Appendix A sketches a possible implementation of the same correlationpattern in standard Java. The implementation is largely incomplete, but still considerably lengthy.

2.3 Streams

EventJava also supports correlation over event streams, through array-like indices on event methods incorrelation patterns defining windows. Consider a simple pattern in fraud detection, which looks for 3different insider trades of a stock with a combined volume ≥ 100000. This pattern specifies the number ofsubsequent insiderTrade events being correlated, and the attributes of each of the events are accessed in thepredicate and reaction body using indices.event insiderTrade[3](String firm, String name, String role, float price, long vol)

when (insiderTrade[0].name != insiderTrade[1].name &&insiderTrade[1].name != insiderTrade[2].name &&insiderTrade[0].name != insiderTrade[2].name &&insiderTrade[0].firm == insiderTrade[1].firm == insiderTrade[2].firm &&insiderTrade[0].vol + insiderTrade[1].vol + insiderTrade[2].vol >= 100000){...}

5

Page 6: EventJava - Purdue University

i < j implies e[i].time < e[j].time, for example with e=insiderTrade above. Aggregated events can ofcourse be correlated with non-aggregated ones. Consider the following algorithmic trading scenario whichseeks a stock decreasing monotonically in value for 10 quotes immediately after an analyst downgrade.event analystDowngrade(String firm1, String analyst, String from, String to),

stockQuote[10](String name, float sPrice)when (analystDowngrade < stockPrice[0] &&for i in 0..9 stockQuote[i].sPrice > stockQuote[i+1].sPrice &&for i in 0..9 stockQuote[i].name == analystDowngrade.name) {...}

A declaration e() without window is in fact simply treated like e[1]().

2.4 Matching Semantics

Event correlation semantics have different parameters [14, 15]. For instance, a pattern event e1(), e2() canbe matched by a sequence of events e1

1, e21, e

12 either as 〈e1

1, e12〉 (FIFO) or 〈e2

1, e12〉 (LIFO). In the latter case,

one might even want to discard the superseded e11. Different semantics can be of interest for different settings.

In tightly coupled concurrency scenarios, the latter suggestion of discarding an event without consuming itseems wrong. In systems with dynamically joining and leaving participants and in the presence of predicates,it becomes infeasible in general to ensure that any event is consumed at least by one object, and obsolescenceof events might be part of the application semantics.

To be able to accommodate various applications, matching in EventJava is implemented as part of aframework explained more in the following sections. Our default semantics presented in the next section arenon-deterministic in that in the above example either outcome is possible. This reflects many concurrencysettings where non-determinism is desired to achieve some form of fairness. The semantics of our referenceimplementation strike a balance between (a) static settings, i.e., where by design and deployment every eventis assured to be consumed by at least one object (possibly by omitting predicates), and (b) dynamic settings.They will be presented in Section 4.2.

2.5 Context

Events can have explicit and implicit meanings. In EventJava, the latter are captured by implicit attributesforming a context. The timestamps (*.time) used in Section 2.2 are but an example – though an importantone. The ordering underlying our matching semantics hinge on this notion.

Implicit event attributes are in fact fields defined globally by a Context class, of which an instance ispassed along with every event. The code required to create and pass this context is generated by our compiler.In the following simple class, an event is simply timestamped with the local physical clock.public class Context implements Comparable<Context> , Serializable {

public long time;... /* more fields */public Context() { this.time = System.currentTimeMillis(); }public Context(long time) { this.time = time; }public int compare(Context other) {if(timestamp == other.timestamp) return 0;...

}...

}

Please note that this is but a simple example, and that the notion of time is generally more complexand has to be closely aligned with the underlying communication infrastructure and the other parts of theframework (see Section 4).

The Context class is verified at compilation for well-formedness. Its public fields f1,f2,...,fq (in the orderof declaration) define the implicit event attributes. Constructors can have formal arguments correspondingto subsequences of those fields. An event method declaration can optionally list the entire context, e.g.event e()[f1,...,fq], and an event method invocation in special cases may want to explicitly provide valuesfor the context corresponding to a constructor, e.g. e()[f1,...,f j], j∈[1..q].

6

Page 7: EventJava - Purdue University

program Q ::= ∅ | Q ||Ti(t;) value v ::= l(A) | new D(d)mutable L ::= class C extends C{T f; K M P} type T ::=C | I | Dimmutable J ::= class I extends I{N f; K M} class A ::=C | Iconstructor K ::=A(T f){super(f); this.f:=f;} attribute N ::= I | Dmethod M ::= T m(T x){t; return t;} pattern P ::= event E when p{t;}event E ::= e[n](N x)[N x] | e[n](N x) filter u ::= u.f | (T)u | new D(d) | x[n] | x[i]predicate p ::= u v-op u | p b-op p | ! p | for i in[n..n] pterm t ::= v | x | t.f | t.f:=t | t.m(t) | (T)t | t.e(t) | t.e(t)[t] | C.e(t) | C.e(t)[t] | new A(t) | new T(t;)

d ∈Dl ∈ dom(L)

n ∈ Z+

(D, d,D)∈{(B, b,B), (I, z,Z), (F, r,R), (S, s,Σ∗), ...}v-op∈{==, <=, <}b-op∈{&&, ||}

Figure 1: Featherweight EventJava (FEJ) syntax.

3 EventJava Syntax and Semantics

This section presents the syntax and semantics of EventJava in more detail. The major additions of Event-Java to Java are reflected in Figure 1, which presents its core as an extension of Featherweight Java (FJ) [12],dubbed Featherweight EventJava (FEJ). FEJ supports illustration, and reasoning about subtyping, inheri-tance, and matching semantics.

3.1 Featherweight EventJava (FEJ) Syntax

As in FJ, this is a special variable x, and o represents a sequence o1...oq; separating symbols – if any – dependon the context. A given element of a sequence is referred to as oj . Two-level nested sequences o are alsopossible; in this case, an individual element can be referred to as okj . The first bar above the o relates tothe subscript index j, whereas the second one refers to the superscript k; ok thus unambiguously representsok1 ...o

kq . Three levels only occur in one case, in which a special notation will be used which removes ambiguity

(o)1..q.In FEJ, a program is a parallel execution of threads of the form Ti(t;); the parallel composition operator

|| is commutative and associative. In Ti(t;), i represents a unique identifier (not necessarily continuouslyassigned). Threads can be created explicitly (new T(t;)) or by the system. Immutable classes are introducedto abstract serialization and cloning. No assignments can occur to fields of such objects, and their fields haveto be recursively immutable. (EventJava applies a simple static analysis to attempt to infer immutabilityand reverts to cloning if it fails.) Immutable classes cannot define patterns. Types (T) encompass (mutable)classes (C ), immutable classes (I ), and value classes (D) which reflect primitive types. B, I, F, S for instancerefer to booleans, integers, floats, and strings respectively. Instances of immutable and value classes are theonly permissible terms for event attributes (N ). FJ’s call-by-value semantics are retained but as in otherextensions (e.g. [16]), we introduce field assignments (t.x:=...) and thus new A(...) terms evaluate to locationsl(A) in memory. The latter terms are not used explicitly in programs; when not relevant, the type A willbe omitted.

Correlation patterns include a sequence of events E , a predicate, and a reaction; events can either declaretheir context ([...]), or omit it. The global context representation is defined as a set of terms ∇t of types?N. To simplify the calculus rules, either all events in a given pattern specify the context or omit it. Apredicate is a conjunction or disjunction (b-op) of simpler predicates. Among those are comparisons of valueobjects (v-op), and universal quantification. An event ej is always defined over a window of size nj≥ 1, withnj commonly 1.

Predicates only allow u terms which represent a strict subgrammar of t, omitting for instance fields ofthis; even if type checking can ensure that a field f is of an immutable type, its value could otherwise change(by reassignment in another thread). In practice, the final modifier helps overcome this limitation.

7

Page 8: EventJava - Purdue University

fields(Object)=∅ [Obj-Class]

CT (E)=class E extends Object{} [Ev-Class]

CT (A)=class A extends A′{T f ; ...}fields(A′)=T ′ f ′

fields(A)=T ′ f ′, T f[Field-Type]

CT (A)=class A extends ...{... M...}T m(T x){t; return t;}∈M

mtype(m,A)=T→T[Meth-Type]

CT (A)=class A extends A′{... M...}6 ∃...m...∈M

mtype(m,A)=mtype(m,A′)[Meth-Type-Inh]

CT (C)=class C extends ...{... P}event... e[n](N x)... {t;}∈Petype(e, C)=n×N ?N→E

[Ev-Type]

CT (C)=class C extends C′{... P} 6 ∃...e...∈Petype(e, C)=etype(e, C′)

[Ev-Type-Inh]

CT (C)=class C extends ...{... P}event e[n](...)...∈Pctype(ej , C)=e→E

[Coll-Type]

CT (C)=class C extends C′{... P}6 ∃...e...∈P

ctype(e, C)=ctype(e, C′)[Coll-Type-Inh]

CT (A)=class A extends ...{... M ...}T m(T x){t; return t;}∈M

mbody(m,A)= (x, t;t)[Meth-Body]

CT (A)=class A extends A′{... M ...}6 ∃...m...∈M

mbody(m,A)=mbody(m,A′)[Meth-Body-Inh]

CT (C)=class C extends ...{... P}

event e[n](Nx)[N ′x′] when p{t;}∈P

rbody(e, C)= (xx′, p, t)[React-Body]

CT (C)=class C extends ...{... P}∀ j fresh xj =xj

1 ...xjq q=|?N|

event e[n](Nx′) when p{t;}∈P

rbody(e, C)= (x′x, p, t)[React-Body-Def]

CT (C)=class C extends C′{... P}6 ∃...e......∈P

rbody(e, C)=rbody(e, C′)[React-Body-Inh]

mtype(m,A) 6= ⊥⇒mtype(m,A)=T→Tmoverride(m,A, T→T)

[Meth-Over]

ctype(ek, C)=e→E⇒∀ j (etype(ej , C) 6= ⊥⇒etype(ej , C)=n×Nj ?N→E, etype(ej , C)=⊥⇒∃ event... ej[n](Nj xj)...∈P) n ≥ nj

poverride(e, C, n,N, P)[Patt-Over]

Figure 2: Auxiliary definitions for FEJ.

3.2 FEJ Definitions

Figure 2 presents the usual lookup function definitions for FEJ. We analogously introduce lookup functionsfor event types, patterns, and for reactions. E is a placeholder class, which has neither methods nor fields.

Figure 3 presents the rules ([...-T]) for subtyping (T � T ’) and static type checking judgements (Γ ` T:t).Note that the context terms ∇t need to be type checked at every place where an event is triggered withoutspecifying a specific context ([Ev-Def-...T]). Note also that x[i] is handled differently from x[n]; x[n] is handledlike variables (in terms, i.e., types are assumed), while x[i] is handled like terms (in filters, i.e., the type isinferred from x).

Figure 4 presents judgements for a class to pass type checking ([...-OK]), and bound checking judgements ([...-

B]). Bound checking on events/event sequences is reminiscent of dependent types, and is performed statically.Υ represents a set of bounds of the form x : n, which means that x is a variable appearing in an eventdeclaration with a window of n elements. ∆ is a set of bounds for variables i introduced with universalquantifications of the form i : [n..n′]. A judgement of the form Υ;∆`u ok means that u respects the boundsof Υ and ∆; the two environments “meet” in [Ev-Ind-B] through terms of the form x[i].

The static bounds n and n′ for the universal quantification need not be checked in [Forall-T], as themetavariable n implies that they are non-negative numbers. The condition n ≤ n′ is verified as part ofboundary checking ([ForAll-B]). The [Patt-...OK] rules ensure that no event is declared over a window of size 0.

3.3 Typing

The constructs added to Java by EventJava come with several typing constraints.

8

Page 9: EventJava - Purdue University

T�T’T�T [Refl-S]

T�T ′ T ′�T ′′

T�T ′′[Trans-S]

CT (C)=class C extends C′{...}

C�C′[Decl-S]

Γ`t:T

x :T∈Γ

Γ`x :T[Env-T]

Γ`t :A fields(A)=T f

Γ`t.fi :Ti[Field-Acc-T]

Γ`t :C Γ`t′ :T ′ T ′�Tj

fields(C)=T f

Γ`t.fj:=t′ :Ti

[Field-Ass-T]

mtype(m,A)=T→TΓ`t :A Γ`t :T ′ T ′�T

Γ`t.m(t) :T[Meth-T]

fields(A)=T f

Γ`t :T ′ T ′�TΓ`new A(t) :A

[Cons-T]

d∈D(D, d,D)∈

{(B, b,B), (I, z,Z), (F, r,R), ...}Γ`new D(d) :D

[Val-Cons-T]

Γ`t :T

Γ`new T(t;) :T[Thread-T]

Γ`t :T T ′ 6�T T 6�T ′stupid warning

Γ`(T ′)t :T ′[SCast-T]

Γ`t :T T�T ′

Γ`(T ′)t :T ′[UCast-T]

Γ`t :T T ′�T T ′ 6= T

Γ`(T ′)t :T ′[DCast-T]

etype(e, C)=n×N ′′ ?N→EΓ`t :C Γ`t′ :N N�N ′′

N ′�?N Γ`t′′ :N ′

Γ`t.e(t′)[t′′] :E[Ev-T]

etype(e, C)=N ′ ?N→EΓ`∇t :?N Γ`t :C

Γ`t′ :N N�N ′

Γ`t.e(t′) :E[Ev-Def-T]

etype(e, C)=N ′′ ?N→EN ′�?N Γ`t :N

N�N ′′ Γ`t′ :N ′

Γ`C.e(t)[t′] :E[Ev-Bcast-T]

etype(e, C)=N ′ ?N→EΓ`∇t :?N Γ`t :N N�N ′

Γ`C.e(t) :E[Ev-Def-Bcast-T]

Γ`t :D Γ`t′ :D D 6= B

Γ`t v-op t′ :B[Comp-T]

Γ`t :B Γ`t′ :Bb-op′∈{b-op} ∪ {==}

Γ`t b-op′ t′ :B

[Bool-T]

Γ`t :B

Γ` !t :B[Bool-Neg-T]

Γ`p :B

Γ`for i in[n..n′] p :B[Forall-T]

Γ`x :T

Γ`x[i] :T[Ev-Ind-T]

Figure 3: Typing rules for FEJ.

3.3.1 Integration with Java RMI

Several constraints in EventJava come from its integration with the Java RMI framework [17]. This does notmean that remote communication in EventJava takes place over Java RMI. EventJava is merely integratedwith the interfaces, for portability and interoperability with J2EE.

The integration implies that events must be declared in interfaces subtyping java.rmi.Remote (omitted inthe examples so far for brevity), which means that sinks are remote objects. Event methods become therebypublic, and can not be static. These last two restrictions are effortlessly transposed to FEJ, as bare FJonly supports public and non-static members.

3.3.2 Constraints on event methods

Event methods are specific methods, and their declaration and implementation thus follows special restric-tions.

1. Event methods cannot throw exceptions and cannot return values. Their return type is event. (Thissimplifies broadcast – see Section 7).

2. Event method headers cannot be synchronized, as this would contradict their asynchronous nature.Reactions may be defined to be synchronized though by adding the keyword in front of the correlationpattern declaration.

3. Similarly, final applies to correlation patterns. By prefixing a correlation pattern with that keyword, allevent methods in the correlation pattern are transitively made final, and none of them can be overriddenin a subclass correlation pattern.

9

Page 10: EventJava - Purdue University

Υ;∆`u ok

Υ; ∆ ` new D(d) ok[Val-Constr-B]

Υ; ∆ ` u okΥ; ∆ ` u.f ok

[Field-Acc-B]

Υ; ∆ ` u okΥ; ∆ ` (T)u ok

[Cast-B]

Υ; ∆ ` u okΥ,∆ ` u′ ok

Υ; ∆ ` u v-op u′ ok[Comp-B]

x :n∈Υi : [n′..n′′]∈∆n′′≤n−1

Υ; ∆ ` x[i] ok[Ev-Ind-B]

Υ;∆`p okΥ; ∆ ` p okΥ; ∆ ` !p ok

[Bool-Neg-B]Υ; ∆ ` p ok Υ; ∆ ` p′ ok

Υ; ∆ ` p b-op p′ ok[Bool-B]

Υ; ∆, i : [n..n′] ` p ok n≤n′

Υ; ∆ ` for i in[n..n′] p ok[Forall-B]

A okΓ=x[n′] :N, x′[n′] :?N

CT (C)=class C extends C′{... P} n≥1

poverride(e, C′, n,N, P) n′j ∈ [0..nj − 1]

Γ`p :B Γ, this :C`t :T ′ x :n, x′ :n; ` p ok

event e[n](N x)[?N x′] when p{t;} ok in C[Patt-OK]

x :T, this :A`t t :T ′T ′ T 6=TCT (A)=class A extends A′{...}moverride(m,A′, T→T) T ′�TT m(T x){t; return t;} ok in A

[Meth-OK]

CT (C)=class C extends C′{... P} n≥1

poverride(e, C′, n, T, P)

n′j ∈ [0..nj − 1] Γ=x[n′] :N

Γ`p :B Γ, this :C`t :T ′ x :n; `p

event e[n](N x) when p{t;} ok in C[Patt-Def-OK]

K=A(T ′ f ′,T f){super(f ′);this.f:=f;}M ok ∈ C fields(A′)=T ′ f ′

P 6=⊥⇒P ok in A

class A extends A′ {T f;K M P} ok[Class-OK]

Figure 4: Bound checking and class well-formedness rules for FEJ.

4. An event method can only appear in a single correlation pattern within a class. Without this restriction,semantics become much more complicated – the same instances of a given event could be consumed indifferent orders by distinct patterns involving that event due to differing respective interplays with otherevent types and predicates. Worse even, the distinct patterns could match different sets of events ofa same type, possibly requiring events to be stored per-pattern. Events can be multiplied manually ifrequired.

5. Predicates, like reactions, can not be defined in interfaces. An interface, or a class, can define an abstract

event correlation pattern, which is strictly the same as defining the respective event methods individually.

6. A reaction body may make a call to a reaction body of a pattern involving the same set of events in itssuper-class through super.

In FEJ, 1 is achieved by the introduction of the placeholder E. 2, and 3 are abstracted. 4, 5, and 6 areenforced by inheriting from FJ.

3.3.3 Overriding

The constraints for event method overriding follow naturally from the rules above and their distinctionof pattern- and event-wide modifiers. Overriding an event method e (with window [n]) is possible (with[n’], n’≥n) iff e is not in a final pattern in the (non-final) super-class. Any event e′ of the overriddenreaction/pattern becomes an orphan and thus must be included in a pattern with a reaction in the subclassas well or it implicitly becomes abstract just like the subclass itself. The predicate defined by [Patt-Over]

captures the constraint that any orphaned e′ must be included in a pattern in the subclass. For conciseness,FEJ does not support reordering of events when overriding patterns.

3.4 Evaluation

We use contextual semantics to model dynamic semantics, introduced in Figure 5. Evaluation takes placeon tuples; in the context of local evaluation −→, such a tuple is a term together with an object store L andan event store S (see Figure 5). The latter type of store represents per-object queues of events of the form

10

Page 11: EventJava - Purdue University

Evaluation contexts

E ::= [] | (T)E |E.f |E.f:=t | v.f:=E |E.m(t)| v.m(E) |E.e(t) |E.e(t)[t] | v.e(E)[t]| v.e(E) | v.e(v)[E] |C.e(E) |C.e(E)[t]|C.e(v)[E] | new A(E) | v;E;t | v,E,t|E v-op t | v v-opE |E b-op p | v b-opE | !E|E; return t | v; returnE

〈Q,L,S〉 =⇒ 〈Q′,L′,S′〉

〈Q ||Ti(v;),L,S〉=⇒〈Q,L,S〉 [Thread-Kill-R]

j fresh

〈Q ||Ti(E[new T(t;)]),L,S〉=⇒〈Q ||Ti(E[]);,L,S ||Tj(t;)〉

[Thread-Fork-R]

〈t,L,S〉−→〈t′,L′,S′〉〈Q ||Ti(E[t];),L,S〉=⇒〈Q ||Ti(E[t′];),L′,S′〉

[Congruence-R]

match(S, l(C), e,N,Θ) j fresh

S′={S(l)\N/S (l)}S rbody(e, C)=(xx′, p, t)〈Θ p,L,S〉−→∗〈new B(true),L,S〉〈Q,L,S〉=⇒〈Q ||Tj(Θ t;),L,S′〉

[React-R]

S(l)=(e, vv′)·S′(l)πeS(l)=(e, vv′)·πeS′(l)

[Ev-Proj-Incl]

S(l)=(e′, vv′)·S′(l)πeS(l)=πeS′(l)

[Ev-Proj-Excl]

S(l)=S′(l)·(e, vv′)·S′′(l) (e, vv′) 6∈S′(l)S(l)\{(e, vv′)}=S′(l)·S′′(l)

[Ev-Rem]

s=s′ ·s·s′′ P (s)

s∈s P (s)[Ev-Incl]

s=s′′ ·s′1 ·...·s′q ·s′′′ P (s′1, ..., s

′q)

s′1..q∈s P (s′1, ..., s′q)

[Ev-Seq-Incl]

(ej , vj v′j)1..nj∈πej

S(l(C))

etype(ej , C)=nj×... rbody(e, C)=(xx′, p, t)

N=S

k∈[1..nj ] (ej , vjv′j)k

Θ={l/this,(vv′)k/ (x[k−1] x′[k−1])k∈[1..nj ]

}

match(S, l(C), e,N,Θ)[Patt-Match]

Figure 5: Contextual semantics of FEJ.

(e, vv′)·(e, vv′)·.... Global evaluation =⇒ is similar to local evaluation, but relates programs instead of terms.−→∗ is the transitive closure of −→ .

The evaluation of redexes holds no surprises. Events are simply added to corresponding queues. Threadforking and killing are similarly straightforward. The core of the semantics is the reaction rule [React-R],which relies on the match() predicate, and uses a number of auxiliary definitions. πeS(l) simply extractsthe subsequence of events of type e from an event queue. Set complement \(...)S(l) and inclusion ∈ followthe usual intuition, but are specified to simplify understanding of the weaknesses of the present semanticsand of the refined semantics for our reference implementation presented in the next section.

The match() predicate simply takes any set of events matching any pattern defined for a given object(∈), regroups the corresponding events (N) and creates a corresponding variable substitution (Θ). In casethe predicate for the pattern evaluates to true, [React-R] simply removes the events from the queue andcreates a new thread (thread pool in practice) to execute the reaction. Note that −→∗ does not produce anyside-effects in L or S , due to the limitations on predicates.

Given the non-deterministic nature of the event matching, paired by the simple reduction of an eventbroadcast to a multi-send in [Ev-Bcast-R], two instances of a same class receiving identical sets of broadcast(only) events will not necessarily correlate the same events. The matching semantics presented here areintentionally weak and serve as default. The handling of broadcast for instance does not assume more thanreliable point-to-point communication.

3.5 Soundness

The semantics presented so far are sufficient to state traditional type safety.

Lemma 3.1 (Bound preservation) Υ; ∆ ` u ok ∧ u−→u’ ⇒ Υ; ∆ ` u′ ok.

Theorem 3.2 (Type preservation) Γ ` t :T ∧ t−→ t’ ⇒ Γ ` t′ :T ′ | T ′�T.

Proofs by induction on derivation of −→ for both of the above. The latter proof hinges on class E, which isused for “results” of event method invocations.

11

Page 12: EventJava - Purdue University

〈t,L,S〉 −→ 〈t′,L′,S′〉

L(l)= [f1 : v1, ..., fq : vq ]

〈l(A).fj ,L,S〉−→〈vj ,L,S〉[Field-Acc-R]

L(l)= [f1 : v1, ..., fq : vq ]

L′={[f1:v1,...,fj :v′,...,fq :vq ]/ l}L〈l(C).fj:=v

′,L,S〉−→〈v′,L′,S〉[Field-Ass-R]

A�T〈(T)l(A),L,S〉−→〈l(A),L,S〉

[Obj-Cast-R]

D�T〈(T)new D(d),L,S〉−→〈new D(d),L,S〉

[Val-Cast-R]

〈v;return v′,L,S〉−→〈v′,L,S〉 [Ret-R]

mbody(m,A)=(x, t)

〈l(A).m(v),L,S〉−→〈{v/x, l/this}t,L,S〉[Meth-R]

〈for i in[n..n′] p,L,S〉−→〈{n/ i}p&&...&&{n′/ i}p,L,S〉

[Forall-R]

〈! new B(b),L,S〉−→〈new B(¬b),L,S〉 [Bool-Neg-R]

(b-op, a-op)∈{(&&,∧), (||,∨)}〈new B(b) b-op new B(b′),L,S〉−→

〈new B(b a-op b′),L,S〉

[Bool-Op-R]

(v-op, a-op)∈{(==,=), (<=,≤), (<,≤)}〈new D(d) v-op new D(d′),L,S〉−→

〈new B(d a-op d′),L,S〉

[Val-Op-R]

〈l.e(v),L,S〉−→〈l.e(v)[∇t],L,S〉 [Ev-Def-R]

S′={S(l)·(e,v v′)/ l}S〈l.e(v)[v′],L,S〉−→〈new E(),L,S′〉

[Ev-R]

fields(A)=T f l 6∈dom(L)

L′={[f1:v1,...,fq :vq ]/ l}L〈new A(v),L,S〉−→〈l(A),L′,S〉

[Loc-R]

〈C.e(v),L,S〉−→〈C.e(v)[∇t],L,S〉 [Ev-Bcast-Def-R]

l={l | l(C)∈L ∧ C�C′}〈C′.e(v)[v′],L,S〉−→

〈l1.e(v)[v′];...;lq.e(v)[v′],L,S〉

[Ev-Bcast-R]

Figure 6: Contextual semantics of FEJ (cont’d).

Theorem 3.3 (Local progress) Suppose t is a closed, well-typed normal form. Then (a) t is a value, or(b) ∃ E | t = E[(T)new T ′(v)] ∧ T ′ 6�T.

Proof by induction on typing derivations, using Lemma 3.1.The progress stated above considers terms of the language, giving no guarantees that events will ever

lead to reactions. In the following we state a global progress property which ties the knots. Consider in thefollowing an object l(C ) with a pattern event e[n](N x)[N x] when p{t;} defined in C .

Definition 1 (Configurations) We refer to C = 〈Q,L,S〉 as a configuration.

• Ekj (Q,L,S) = 〈Ti(E[dj.ej(vj v′j)]k) ||Q,L,S〉 is an event configuration.

• Rel(C)(Θ, Q,L,S) = 〈T〈l(C),e〉(Θt;...) ||Q,L,S〉 is a reaction configuration.

Definition 2 (Run) A run is a succession of configurations C=C1=⇒...=⇒Cq.

Theorem 3.4 (Global progress) Assume a run C s.t. ∀j ∈ [1..q], k ∈ [1..nj ] (i) dkj ∈ l(C) ∪ {C ′ | C �

C ′} (ii) ∃Lkj (l) (iii) ∃C = Ekj (Qkj ,Ljk,Skj ) ∈ C, and also (iv) 〈{l/ this, (vjv′j)k/ (xjx′j )k∈[1..nj ]

}p, ...〉 −→∗

〈new B(true), ...〉. Then ∀C′ = C=⇒C′′ ∃ Rel (Θ, Q,L,S) ∈ C′

Proof by induction on derivation of =⇒. (The theorem reads “If a pattern of an object gets satisfied atleast once, the corresponding reaction will eventually be evaluated.”)

4 Implementation

This section first presents the implementation framework of EventJava. Then, a reference implementationbased on Jess [10] and JGroups [11] is presented along with its specific matching semantics, showing thatthese preserve ordering of events disseminated by JGroups.

12

Page 13: EventJava - Purdue University

4.1 Implementation Framework

The EventJava compiler, implemented using Polyglot [19], translates EventJava programs to standard Javaby (a) code transformations and (b) generation of application-specific helper classes (e.g. for broadcasting).Details of the translation are presented in section 5.

4.1.1 Framework components

The generated code represents the glue between EventJava programs and the framework components shownin Figure 7. An event notification/method invocation is forwarded to the communication substrate, JGroupsin the case of our reference implementation, which takes care of remote communication including unicastand broadcast. In the broadcast case, the substrate delivers all the serialized event method invocations tothe resolver, which determines the classes on which the methods were invoked and interacts with broadcastobjects for those classes. Broadcast objects deliver the events to the sinks, where they are stored, typicallybut not necessarily in event queues. The matcher — one instance per sink — checks the stored events fora match to any of the correlation patterns spawns the reaction on its sink. Multi-threading can be used invarious places, with synchronization depending on the desired semantics. While the substrate and matcher,like the context, are defined as an API, the resolver and broadcast classes are generated by our compiler toavoid costly dynamic invocations through reflection. The context of a given event is used and sometimesmodified or augmented throughout the substrate and the matcher.

Communication substrate

Resolver

Broadcastclasses

Event queue

Matcher

Source Sink

Event queue

Event queue

Figure 7: The EventJava framework. Ovals represent the application. Shaded boxes represent fixed compo-nents; others are customizable.

4.1.2 Code transformations

On the source side, each event method invocation is altered to create the context, serialize the explicitarguments, and invoke the substrate. All the instances of any class C which has at least one event methodneed to be tracked by its broadcast class. To that end, a static field instances is added to every such sinkclass to track all of its instances with weak references. Every new on a sink class is instrumented to add thecreated object to the class’ instances set. Broadcast objects for sink classes recursively store references tobroadcast objects for their sink subclasses. Details of the translation are presented in section 5.

4.2 Deterministic Matching in the Jess Reference Implementation

While non-determinism might be desired in certain cases, a trading algorithm replicated for reliability byrunning several instances of the same class will yield contradictory results with the default semantics inSection 3.4, even if the application-level algorithm is deterministic. Moreover, certain events may never pass

13

Page 14: EventJava - Purdue University

s′1∈1 s s′2...s

′q∈

1 s P (s′1, ..., s′q)

s′1...s′q∈

1 s P (s′1, ..., s′q)

[Ev-First-Incl]

s=s′′′ ·s′1 ·...·s′q ·s′′′′ P (s′1, ..., s

′q)

6 ∃s′′1..q∈s′′′ ·s′1 ·...·s

′q−1 P (s′′1 , ..., s

′′q )

s′1..q∈1 s P (s′1, ..., s

′q)

[Ev-First-Seq-Incl]

l={l | l(C)∈L ∧ C�C′} S′={S(l)·(e,v v′)/ l}S〈C′.e(v)[v′],L,S〉−→〈new E(),L,S′〉

[Ev-Bcast-R’]

match1(S, l(C), e,N,Θ) Q=Q′ ||T〈l,e〉(t′;)

rbody(e, C)=(xx′, p, t) S′={S(l)\∗ N/S (l)}S〈Θ p,L,S〉−→∗〈new B(true),L,S〉〈Q,L,S〉=⇒〈Q′ ||T〈l,e〉(t;Θ t;),L,S′〉

[React-R’1]

match1(S, l(C), e,N,Θ) Q 6=Q′ ||T〈l,e〉(t′;)

rbody(e, C)=(xx′, p, t) S′={S(l)\∗ N/S (l)}S〈Θ p,L,S〉−→∗〈new B(true),L,S〉〈Q,L,S〉=⇒〈Q ||T〈l,e〉(Θ t;),L,S′〉

[React-R’2]

S(l)=S′(l)·(e, vv′)·S(l)′′ (e, vv′) 6∈S′(l)S(l)\∗ {(e, vv′)}=S(l)′′

[Ev-Rem-All]

(ej , vj v′j)1..nj∈1πej

S(l(C))

etype(ej , C)=nj×... rbody(e, C)=(xx′, p, t)

N=S

k∈[1..nj ] (ej , vjv′j)k

Θ={l/this,(vv′)k/ (x[k−1] x′[k−1])

k∈[1..nj ]}

match1(S, l(C), e,N,Θ)[Patt-Match1]

Figure 8: Deterministic matching semantics in the Jess reference implementation.

the corresponding predicate p if that defines constraints on their individual attributes which are not met,which means that these events linger around.

4.2.1 Rete-based matching

Figure 8 presents an alternative deterministic dispatching semantics describing our reference implementationof the matcher on top of the Rete [9] algorithm in Jess [10]. In short, Rete treats events, with their explicitand implicit attributes as typed data. The matcher implementation ensures that predicate evaluation issynchronized for a given sink. Correlation patterns and predicates are encoded by our compiler as Jess rules.The matcher delivers the matched events to a dispatch method. The dispatch method, generated by ourcompiler, has code to receive matched events and use threads from a thread pool to execute the reactionbodies.

4.2.2 Semantics

Matching is performed by always selecting the first possible event (∈1 ), if exists, of the first type in a correla-tion pattern which can trigger the reaction (rule [Patt-Match’]); can is determined by applying∈1 recursivelyto the remainder of the pattern. In other terms, for a correlation pattern event e1(),e2(),...,eq() when p,the first received instance of e1 is chosen for which an instance of each remaining event type e2,...,eq hasbeen received such that the predicate p is matched; if there are several instances of e2 for which, togetherwith the selected instance of e1, the above applies for the remaining e3,...,eq, then the first one is chosena.s.o. In the case of streams, instead of the first event the first sequence of consecutive events is chosen.

Once a match is determined for a given correlation pattern, any event which is of an event type within thecorrelation pattern and older than the respective matching one(s) is discarded in addition to the matchingone(s), as shown in [\∗ ]. Furthermore, reactions for a same correlation pattern on a same object are executedstrictly sequentially in the order in which they are identified, by identifying threads by a 〈object, pattern〉tuple ([React-R’1,2]). Last but not least, to achieve the desired determinism for broadcast events (impossiblein the presence of unicast), an alternative rule needs to be introduced for this ([Ev-Bcast-R’]), which mirrorsJGroups’ total order broadcast protocol. This feature can be disabled if an application does not require theordering guarantees.

4.2.3 Ordering properties

Consider Definitions 1 and 2 for configurations and runs given in Section 3.5. Using rules [...-R’...] in Figure 8to substitute the respective weaker ones [...-R] of Figures 5,6, we can show that ordering at the JGroups level is

14

Page 15: EventJava - Purdue University

preserved by the matching semantics. Assume l(C ) and l’(C ), and pattern event e[n](N x)[N x] when p{t;}defined in C .

Theorem 4.1 (Order preservation) Assume a run C s.t. ∀C = Ekj (Q,L,S) ∈ C dkj 6∈ {l(C), l′(C)}.Then ∀Ci, Ci′ , Cj , Cj′ ∈ C | Ci = Rel (Θ, Qi,Li,Si), Ci′ = Rel (Θ′, Qi′ ,Li′ ,Si′), Cj = Rel′(Θ, Qj ,Lj ,Sj),

Cj′ = Rel′(Θ′, Qj′ ,Lj′ ,Sj′) i < i′ ⇔ j < j′.

Proof by induction on derivation of =⇒. (The theorem reads: “For two instances of a same class receivingonly broadcast events, the objects will execute reactions to a given pattern in the same respective order.”)

5 Translating EventJava to Java

This section presents the implementation of EventJava, consisting of two parts: (1) a compiler implementedusing Polyglot [19] which translates EventJava programs to standard Java by (1.a) code transformations and(1.b) generation of application-specific helper classes (e.g. for broadcasting), and (2) an implementation ofthe customizable framework components (i.e., the matcher and substrate).

public class Event implements Comparable<Event>, Serializable {public String classN,public String eventN;public Context ctxt;public Object[] args;public Event(String cls, String evN, Context c, Object ... args) {...}...

}

public class Substrate {public static void unicast(Remote sink, Event ev) ...public static void broadcast(Event ev) ...public static void join(String typeN, String[] filers) ...public static void leave(String typeN) ......

}

Figure 9: Excerpt of API for the EventJava framework:Event and Substrate classes

5.1 Transformations

Code transformation and generation is illustrated in the following through the example of Figure 10, focusingon the more involving broadcast case. Figure 10 shows an excerpt of a larger automated stock trading systemimplemented in EventJava. Figure 9 shows parts of the EventJava framework used in the translation.

5.1.1 Sink side

Event method arguments are erased and replaced by a single argument of type Event. In sink classes, amethod with such an argument is generated for every event method. The original method is only retainedin the case of a collection with a single event, where it will represent the reaction.

Furthermore, all the instances of any class C which has at least one event method need to be tracked forbroadcasting. To that end, a static field is added to every such sink class to track all of its instances (seeFigure 11). Every new call to create an instance of a sink class is transformed to include a call to the class’sregister() method, which is added at compilation to populate the instances set of the class. For example,StockMonitor s = new StockMonitor(...);

is transformed toStockMonitor s = new StockMonitor(...).register();

15

Page 16: EventJava - Purdue University

Reactions are transformed to methods, whose name is given by concatenating the corresponding eventnames as shown in Figure 11.

5.1.2 Source side

On the source side, each event method invocation is instrumented such as to (1) create the context, (2)marshall the explicit arguments into an Event and (3) pass it to the substrate. For instance, a broadcastinvocationStockMonitor.stockPrice("IBM", 30, 25)

for the example in Figure 10 is translated to the following:Context c = new Context();Substrate.broadcast(new Event("StockMonitor", "stockPrice", c, "IBM", 30, 25))

interface StockEvents {/* value of current stock quote, opening is value when trading started */event stockPrice(String firm, float val, float opening);

/* stock analysts prediction of the target price of a stock */event analystForecast(String firm, float target);

/* NASDAQ index reflects the trends in technology market */event NASDAQIndex(float val, float opening);

}

public class StockMonitor implements StockEvents {private Portfolio p;public event

stockPrice(String firm, float val, float opening),analystForecast(String firm1, float target)

when (firm == firm1 && analystForecast < stockPrice &&val > target) {

p.RecommendSell(firm);}... /* Other methods, collections and reactions */

}

public class StockMonitor2 extends StockMonitor {...}

Figure 10: Exerpt of EventJava stock trading program with a stock monitor class

5.2 Helper Classes

Delivering events requires more than tracking the instances of sink classes. These instances also have to bereached by the substrate.

5.2.1 Broadcast classes

For each sink class C, a class CBroadcast is generated to broadcast corresponding event method calls (seeFigure 7). A method is added to this latter class for every event method in C. Figure 12 illustrates thisthrough the stockPrice() method which receives an Event originating from a local or remote invocation,and forwards it to all local instances of StockMonitor.

When there is inheritance among sink classes, broadcast classes recursively store references to broadcastclasses corresponding to their immediate subclasses. In Figure 12, class StockMonitorBroadcast has a set ofsubclasses called children, and a method called register() which populates the set. A static instance ofeach broadcast class is created as shown in Figure 12 where it is used to link class StockMonitor2Broadcast toclass StockMonitorBroadcast. Similarly, an IBroadcast class is generated for each interface I with an eventmethod. IBroadcast has a reference to the broadcast classes corresponding to each class that implements

16

Page 17: EventJava - Purdue University

public class StockMonitor extends RemoteObjectimplements CollectionExec {

private static HashSet<StockMonitor> instances;private Portfolio p;private Matcher m;

public void register() {instances.add(this);m = new Matcher().initialize(this, new String[]{...});}public void stockPrice(Event ev) {m.deliver(ev);m.match();

}public void analystForecast(Event ev) {m.deliver(ev);m.match();

}public void stockPrice$analystForecast(String firm,

float val, float opening, ...) {p.RecommendSell(firm);

}public void react(String collection, Event[] matchedEvents) {if (collection == "stockPrice$analystForecast")...

}... /* remainder of class StockMonitor */

}

Figure 11: Tranformed StockMonitor class.

I. See Figure 12 for the StockEventsBroadcast class corresponding to the interface in Figure 10. The staticinstance of class StockMonitorBroadcast is used to link it to StockEventsBroadcast, as shown in Figure 12.

5.2.2 Resolver

One leg is still missing for the delivery of events on sinks. The Substrate namely deals with generic events,which contain information on the corresponding destination type (in the broadcast case). The resolver usesthis information to call the event method on the corresponding broadcast classes. This resolver is alsogenerated by the EventJava compiler, employing switch statements instead of costly introspection.

5.3 Substrate

Our default Substrate class is implemented with JGroups [11]. Besides simply translating the calls madeto the generic API offered by the substrate to the JGroups API, our implementation also deals with themapping from sink classes and interfaces to broadcast groups. This happens by collapsing all sink classes ina class hierarchy rooted at a direct descendent of RemoteObject (such as StockMonitor) into one such group,referred to as sink group. Occurrences of all events in all the classes in such an sink group are broadcastthrough that group. Besides providing consistency in the case of ordering guarantees applied at the broadcastlevel (any common destination set of concurrent events is included in one sink group), this solution balancesbetween the two extreme cases of (1) using a single group to broadcast all events to all sinks (leading tospurious deliveries and thus a performance bottleneck) and (2) using a group per sink class (leading to a largeoverhead for managing these groups, and redundant information in membership tables). A global group iscreated for bootstrapping and coordination; it represents a group delimiting an application and requires acorresponding parameter at startup.

17

Page 18: EventJava - Purdue University

public class StockEventsBroadcast {/* classes that implement StockEvents */private static HashSet<StockEvents> children;public static void register(StockEventsBroadcast ib) {children.add(ib);

}public void stockPrice(Event ev) {/* broadcast events to the implementing classes */for(StockEventsBroadcast ib : children)

ib.stockPrice(ev);}... // same schema for analystForecast and NASDAQindex

}

public class StockMonitorBroadcastextends StockEventsBroadcast implements StockEvents {

private static StockMonitorBroadcast instance =new StockMonitorBroadcast();

static { StockEventsBroadcast.register(instance); }private static HashSet<StockMonitorBroadcast> children;public static void register(StockMonitorBroadcast b) {children.add(b);

}

public void stockPrice(Event ev) {for(StockMonitor sm : StockMonitor.instances)

sm.stockPrice(ev);for(StockMonitorBroadcast cb : children)

cb.stockPrice(ev);}public void analystForecast(Event ev) {for(StockMonitor sm : StockMonitor.instances)

sm.analystForecast(ev);for(StockMonitorBroadcast cb : children)

cb.analystForecast(ev);}

}

public class StockMonitor2Broadcastextends StockMonitorBroadcast {

private static StockMonitor2Broadcast instance =new StockMonitor2Broadcast();

static { StockMonitorBroadcast.register(instance); }...

}

Figure 12: Broadcast classes for StockEvents, StockMonitor, and StockMonitor2.

Figure 13: Sequence diagram showing the transmission of an event from the source to the sink

18

Page 19: EventJava - Purdue University

6 Evaluation

This section analyzes performance of our reference implementation of EventJava (referred to as EventJava)by comparison with (a) the highly tuned Cayuga correlation engine [4] and (b) lightweight limited correlationfor concurrency in Cω [13]. All tests use the more resource-demanding \ semantics (see Section 7).

6.1 Cayuga

Cayuga [4] is a highly tuned, database-backed, correlation engine. All measurement scenarios and settingswere taken from [4] to not favor EventJava. Figure 14 compares the throughput of EventJava with Cayugawith respect to the number of different event methods/event types involved per sink.This experiment wasconducted on an iMac dual core 2.0Ghz with 2GB RAM. Sink classes were generated with 1000, ... ,150000event methods and 4 event methods per correlation pattern, i.e. for the sink class with 100,000 eventmethods, there were 25,000 correlation patterns. The throughput (number of events processed per second)of EventJava remains well above 10,000 events/sec even for the case involving 150,000 event methods and37,500 correlation patterns, even outperforming Cayuga. Note though that according to [4], Cayuga scalesrelatively better than EventJava, performance with EventJava drops relatively sharper beyond 150,000 eventmethods per sink. Cayuga’s throughput drops beyond 10,000 event types, but Cayuga can scale even upto 400,000 event types (their throughput is 2000 events/sec at 400,000 event methods). Also, Cayuga’smemory footprint is smaller than EventJava. We weren’t able to reproduce these results, and use thefigures from [4] to plot the graph. Note that only one sink is used because Cayuga has a single correlationengine and the goal is to compare peak throughput of matching. We conclude that even when implementedwith custom off-the-shelf components such as Jess, the performance of EventJava is comparable to a highlytuned correlation engine in substantial load scenarios. This illustrates that the high-level programmingabstractions of EventJava and its resulting gains in safety, (e.g. when compared to queries expressed inSQL-like grammars) do not entail any inherent penalty.

0

5000

10000

15000

20000

25000

0 20000 40000 60000 80000 100000120000140000160000

Throughp

ut(e

vents/s)

#ofeventmethods/eventtypes

EventJava

Cayuga

Figure 14: Simple throughput comparison of Event-Java and Cayuga.

14000

14200

14400

14600

14800

15000

15200

15400

0 200000 400000 600000 800000 1000000 1200000

Throughp

ut(events/s)

#ofevents

4perpa-ern

8perpa-ern

12perpa-ern

16perpa-ern

20perpa-ern

Figure 15: EventJava throughput with respect tonumber of event methods per pattern.

6.2 Complexity of Correlation Patterns

Figure 15 illustrates the scalability of EventJava with respect to the number of event methods in a correlationpattern. The experiment was conducted using a single sink with 100,000 event methods. So, if there are 4event methods per correlation patten, there are 25,000 correlation patterns. The throughput increases slightlywith the number of events in the pattern, and in all cases the throughput is well above 14,000 events/sec.Figure 15 shows five such scenarios with 4, 8, 12, 16, and 20 event methods per pattern respectively. InFigure 15, we measure throughput by randomly generating events. The throughput remains fairly constant,irrespective of the number of events used in the measurement. For each scenario, we measure average

19

Page 20: EventJava - Purdue University

throughput over streams of 100,000 events to 1 million events. The variation in throughput for any scenariois within 250 events per second, i.e. ∼2%. This shows that the throughput of EventJava does not decreaseover time when it faces continuous streams of events. This experiment was conducted on an iMac 2.0 Ghzdual core with 2GB RAM.

6.3 Cω

Cω/Polyphonic C# [13] implements the Join calculus [29] in C#. Superficially its syntax resembles that ofEventJava, without broadcast and predicates. Cω targets concurrent programming, supporting as syntacticsugar one synchronous method per pattern at most. In the absence of predicates, Cω’s implementation isvery lightweight. Calls to asynchronous methods part of a pattern (or chord in Cω terminology) are queued,and a reaction can be dispatched when every method in the pattern has been called. The matching semanticscorrespond to those described in the default semantics of EventJava. In Figure 16, we measure the matchingperformance of EventJava with Cω for predicate-less patterns which favors the concurrency scenarios aimedat by Cω. The measurements in this case were conducted on an HP PC with an Intel quad core 2.4Ghzprocessor and 3.5GB RAM.The throughput of EventJava is actually 18-19% higher than that of Cω, whichshows the versatility of the reference implementation of EventJava. We conclude that EventJava can be analternative to Cω for concurrent programming. Note that the introduction of predicates is in fact debatedin [13], but not realized to retain the lightweight matching implementation.

0

5000

10000

15000

20000

25000

30000

35000

0 20 40 60 80 100 120

Throughp

ut(e

vents/s)

#ofeventtypes

EventJava

Figure 16: Simple throughput comparison of Event-Java and Cω.

0

20000

40000

60000

80000

100000

120000

0 200 400 600 800 1000 1200

Latency(m

s)

#ofsinks

EventJava

Figure 17: End-to-end latency of EventJava applica-tion with respect to the number of sinks on differentnodes.

6.4 EventJava Latency

For completeness, and to argue for the integration of a broadcast substrate in EventJava, we evaluate the end-to-end latency of EventJava in a distributed settting. Latency here is measured as the time interval betweenthe production of the last event that instantiates a correlation pattern, and the dispatch of the correspondingreaction at a possibly remote sink. For example if two events e1, e2 are used to match a pattern, and if thereaction at the remote sink is dispatched at time t, then the end-to-end latency is t−max(e1.time, e2.time).These measurements were conducted in a local area network, where clocks of hosts were closely synchronized.Figure 17 compares the average latency of EventJava with that of the same application implemented Cωwith .NET Remoting. The sink objects were distributed in groups of 100 on 1, 3, 5, 7, 9, 11 nodes and thesource was on a different node. Each node was a Dell OptiPlex GX270 Workstation with a 3Ghz Pentium4 processor and 512 MB RAM running Microsoft Windows XP. Figure 17 shows that average end-to-endlatency remains closely constant in the EventJava application as the number of sinks increases, while averagelatency rapidly increases when performing a blunt multi-send with .NET Remoting.

20

Page 21: EventJava - Purdue University

7 Discussion

We discuss issues related to the design and implementation of EventJava, including three parameters affectingmatching that can be set by programs (bold):

7.1 Broadcast vs Multicast

Through the presence of predicates in EventJava, broadcasting leads to implicit multicasting, as not allinstances of a sink class C (and of its subsclasses) will necessarily deliver a given event C.e(...). An interme-diate case between unicast and implicit multicast consists in an explicit multicast where a select set of sinksare addressed – atomically as opposed to a multi-send as portrayed in rule [Ev-Bcast-R] of Figure 6. Severalmiddleware systems propose such protocols natively, or they can be built on top. EventJava supports suchinteraction through specific proxies. As the invocation then occurs just like a regular unicast invocation (onthe proxy) and many authors have elaborated on that in the past (e.g., [20, 21]) we omitted its presentation.

7.2 Bootstrapping and Groups

Bootstrapping of EventJava components occurs like in any distributed application: a federated name isnecessary for connecting parties. This name defines a group, which delimits an EventJava application andthereby also broadcasts. There are several ways of further reducing the scope of broadcasts. Two dynamicsolutions are alluded to above. (1) By adding a name attribute to corresponding events, sinks can usepredicates to specify subgroups of interest. (2) Explicit multicast groups can be created by the use of proxiesand libraries. (3) Configuration files can be used to define boundaries for broadcasts on a per-event basis,e.g., through subnet masks.

7.3 Order

The ordering property stated above only holds for two instances of a same class, and with respect to individualpatterns. By matching following the patterns of a class in a deterministic order, which can beenabled in our implementation, the property can be widened to reactions to all patterns of two instancesof a same class. Given the possibility of redistributing events across patterns and redefining predicates insubclasses, widening to subclasses is not possible straightforwardly. Similarly, causal order [22] is a usefulproperty in asynchronous distributed systems devoid of synchronized clocks, e.g. for debugging. It can beinherently achieved with total order broadcast and local order [23] (the substrate will not disseminate an eventbefore any event that causally preceded that event locally), which our reference implementation provides, insettings considering only individual events. With correlation, it can only be provided in a restricted manner.In fact correlation motivates a relaxed notion causal ordering, so that related causally related events can bereceived simultaneously by a reaction, as long no event is received before any antecedents.

In EventJava, causality can be currently violated through data-flow dependencies, or even control-flowdependencies. If a reaction body triggered upon a broadcast event e1 calls a regular method or performsanother action which eventually leads to broadcasting an event e2, the causal link is lost. Though unlikely, theeffect (e2) can become visible before the cause (e1) to certain parties. Tracking all dependencies throughouta program execution however requires information to be passed along with any action, which can not beachieved without runtime support or a worst case instrumentation of every single method invocation and fieldaccess. The optional access to the event context, and explicit passing of it along regular method invocationchains, provides a pragmatic workaround for situations where such complete information is necessary.

7.4 Garbage Collection

Predicates add to the possibility of events never being matched – or matchable. Our reference implementationunderstands type-A and type-B predicates: while the latter refer to elementary predicates involving attributesof different events, the former involve attributes of a single event which can be used to identify and discard

21

Page 22: EventJava - Purdue University

Language Flexible Joins Type-A Type-B Streams Addressingmatching predicates predicates

ECO [24] - - 4 - - BroadcastJavaPS [25] - - 4 - - Broadcast

Cω [13] - 4 - - - UnicastJoin Java [18] - 4 - - - UnicastAWED [26] 4 4 - 4 - BroadcastCML [28] 4 4(staged) 4 - - Broadcast

StreamFlex [30] 4 4 - - 4 UnicastStreamIt [31] 4 4 - - 4 UnicastPtolemy [39] 4 4(staged) - - - Unicast

Table 1: Overview of inherent event programming features of related programming languages/frameworks.Languages supporting broadcast also have unicast.

events that are unmatchable. Despite this measure, events of a given type can accumulate if events of othertypes correlated with it are received at lower rates. Our reference implementation thus allows for the settingof time-outs on events, by sources (context) and sinks. Furthermore, the deletion of all earlier events ofa type when identifying the first one matching its pattern ( \∗ in rules [React-R’1,2]) can be similarly disabled,leading to retaining older non-matched events (by using \ instead). It is easy to show that this doesnot invalidate Theorem 4.1.

7.5 Return Values

Cω [13] (see Section 8) supports at most one synchronous method per pattern as syntactic sugar. A similarextension is being investigated for EventJava, consisting in introducing synchronous event methods whichallow only value objects as arguments and return values. Furthermore, broadcast would be disabled forthose methods to avoid multiple return values.

8 Related Work

The literature on distributed and concurrent systems describing a notion of events is very vast. We presentin the following related work on programming language support for event-based programming with emphasison correlation. An overview of the most closely related languages/frameworks is given in Table 1.

8.1 Concurrency

Like Cω [13], Join Java [18] faithfully implements the Join calculus [29] – providing a means to react tocorrelated asynchronous method invocations, without predicates, broadcast, and customizable matchingthough. CML [28] provides powerful support for events, which is only partly matched by other functionallanguages (e.g. Erlang [27]). Events are essentially reified function evaluations such as reads or writes onchannels, which can be combined. Event correlation can be achieved by a staged event matching, where theoccurrence of an event of a first type is a precondition for the remaining matching, which consumes that event.This gives the programmer much control over the exact matching semantics, but means implementing partialmatching schemes repeatedly. In many cases, more advanced schemes expressed with staged matching canrequire “re-inserting” an event, which quickly complicates code. CML provides rich libraries with commonoperators to mitigate the issues above.

Jeeg [32] is a concurrency extension of Java imposing ordering of method invocations based on patternsdescribed in Linear Temporal Logic (LTL) in a way similar to the routines in many active object approaches,

22

Page 23: EventJava - Purdue University

e.g., [33]. Like CML these approaches do however not allow for the atomic reaction to combinations ofincoming calls/events. Responders [34] provide a means of writing responsive threads in a state-machinemanner, yielding an effective, safe, and flexible way of arranging event handling code. However, correlationis not supported, and reactions are synchronous to ensure determinism.

8.2 Publish/subscribe, Streams, and Flows

ECO (events, constraints, objects) [24] and JavaPS [25] extend C++ and Java respectively for publish/subscribe-like distributed programming, i.e., reacting to singleton events. StreamIt [31] is a dataflow language targetingfine-grained highly parallel stream applications and providing a highly optimizing native compiler (and aJava translator). While StreamIt programs can be parallelized automatically, the language is hardly suitedfor general purpose applications because of the paucity of data types offered and the restricted programmingmodel. Also, there is no support for event correlation or stream correlation. StreamFlex [30] is a Java API forstream processing inspired by StreamIt but providing high-predictability implemented on top of a real-timevirtual machine. StreamIt provides filters and channels, leading to a similar programming model as CML.DirectFlow [35] is a domain specific language that simplifies programming information-flow components byhiding the control-flow interactions between them. Again, there is no explicit support for event correlation.Cω has also been added support for streams [36], which, like StreamIt or StreamFlex, allows for explicitlyiterating over a stream. These streams are not integrated with chords, yet are more closely integrated withthe other language features in Cω, through special stream types which can be viewed as pointers to/iteratorsover a priori endless arrays.

8.3 Aspects

Several authors describe extensions of aspect-oriented programming for distributed systems, through theaddition of distributed pointcuts, which allow for event correlation. The DADO (distributed aspects fordistributed objects) [37] middleware offers an innovative IDL language for programming distributed aspectsin heterogeneous environments. DADO includes a remote multiple contextual invocation (RMCI) mechanismthat provides a form of dynamic per-invocation selection of aspects. However this mechanism is restrictedto the scope of a single client-server interaction. Another example of aspect language supporting the remotemonitoring of distributed applications with distributed pointcuts and advice is AWED (aspects with explicitdistribution) [26]). EventJava can be viewed as AWED turned inside-out: applications are intentionallywritten to interact with specific events, which is achieved by the means of limited additional syntax. DJ-cutter [38] extends AspectJ’s with remote joinpoints and pointcuts. However, at the runtime level, DJcutterproposes a centralized aspect-server, which constitutes a bottleneck in a large distributed systems; as manyothers of the others, DJcutter lacks consistency guarantees as a consequence of poor integration with dis-tribution. Ptolemy [39] is an aspect-oriented language with quantified, typed events, but doesn’t supportcorrelation - joins can be performed in a staged manner as described earlier.

9 Conclusions and Outlook

We have presented EventJava, an expressive language for generic event-based programming with eventcorrelation. Our implementation framework allows for adaptation to various settings and systems. We arefor instance in the process of implementing a lightweight version of EventJava for mobile computing. Thenotion of context allows us to easily accommodate context-aware applications.

We are currently pursuing two further axes of research, centered around matching semantics and theEventJava framework. First, we are devising annotations for flexibly configuring matching semantics on aper-pattern basis. Second, we are investigating the use of domain-specific aspects for context expression andpropagation and other parts of our framework.

23

Page 24: EventJava - Purdue University

10 Acknowledgements

The authors would like to thank Ryan Maus at Allston Trading LLC for input on the algorithmic tradingexamples, and Jacob Fancher for his contribution to the EventJava compiler.

References

[1] Trigeo: TriGeo Security Information Manager (Trigeo SIM). (2007) http://www.trigeo.com/products/detailedf/.

[2] Chakravarthy, S., Mishra, D.: An Expressive Event Specification Language for Active Databases. DataKnowledge Engineering 14(1) (1994) 1–26

[3] Gay, D., Levis, P., von Behren, R., Welsh, M., Brewer, E., Culler, D.: The nesC Language: A HolisticApproach to Networked Embedded Systems. PLDI’03. 1–11

[4] Brenna, L., Demers, A., Gehrke, J., Hong, M., Ossher, J., Panda, B., Riedewald, M., Thatte, M., White,W.: Cayuga: a High-performance Event Processing Engine. SIGMOD ’07. 1100–1102

[5] Abadi, D.J., Carney, D., Cetintemel, U., Cherniack, M., Convey, C., Lee, S., Stonebraker, M., Tatbul,N., Zdonik, S.: Aurora: A New Model and Architecture for Data Stream Management. VLDB Journal12(2) (2003) 120–139

[6] Ahmad, Y., Berg, B., Cetintemel, U., Humphrey, M., Hwang, J.H., Jhingran, A., Maskey, A., Papaem-manouil, O., Rasin, A., Tatbul, N., Xing, W., Xing, Y., Zdonik, S.: Distributed Operation in theBorealis Stream Processing Engine. SIGMOD ’05. 882–884

[7] Spread Concepts LLC: The Spread Toolkit. http://www.spread.org.

[8] Pietzuch, P.R., Bacon, J.: Hermes: A Distributed Event-Based Middleware Architecture. ICDCSWorkshops ’02. 611–618

[9] Forgy, C.: Rete: a Fast Algorithm for the Many Patterns/Many Objects Match Problem. ArtificialIntelligence 19(1) (1982) 17–37

[10] Friedman-Hill, E.: Jess, http://www.jessrules.com/jess/. (2008)

[11] Ban, B.: JGroups - A Toolkit for Reliable Multicast Communication, http://www.jgroups.org/javagroupsnew/docs/index.html. (2007)

[12] Igarashi, A., Pierce, B.C., Wadler, P.: Featherweight Java: A Minimal Core Calculus for Java and GJ.TOPLAS 23(3) (2001) 396–450

[13] Benton, N., Cardelli, L., Fournet, C.: Modern Concurrency Abstractions for C#. TOPLAS 26(5)(2004) 769–804

[14] Chakravarthy, S., Krishnaprasad, V., Anwar, E., Kim, S.K.: Composite Events for Active Databases:Semantics, Contexts and Detection. VLDB’94. 606–617

[15] Sanchez, C., Slanina, M., Sipma, H., Manna, Z.: Expressive Completeness of an Event-Pattern ReactiveProgramming Language. FORTE’05. 529–532

[16] Strinisa, R., Sewell, P., Parkinson, M.: The Java Module System: Core Design and Semantic Definition.OOPSLA ’07. 499–514

[17] Sun: Java Remote Method Invocation (Java RMI). (2004) http://java.sun.com/j2se/1.5.0/docs/guide/rmi/.

24

Page 25: EventJava - Purdue University

[18] Itzstein, S.V., Kearney, D.: The Expression of Common Concurrency Patterns in Join Java. PDPTA’04. 1021–1025

[19] Nystrom, N., Clarkson, M.R., Myers, A.C.: Polyglot: An Extensible Compiler Framework for Java. CC2003. 138–152

[20] Black, A., Immel, M.: Encapsulating Plurality. ECOOP ’93. 56–79

[21] Guerraoui, R., Garbinato, B., Mazouni, K.: GARF: A Tool for Programming Reliable DistributedApplications. Concurrency 5(4) (1997) 29–32

[22] Lamport, L.: Time, Clocks, and the Ordering of Events in a Distributed System. CACM 21(7) (1978)558–565

[23] Toinard, G.F.C.: A New Way to Design Causally and Totally Ordered Multicast Protocols. OSR 26(4)(1992) 77–83

[24] Haahr, M., Meier, R., Nixon, P., Cahill, V., Jul, E.: Filtering and Scalability in the ECO DistributedEvent Model. PDSE 2000. 83–92

[25] Eugster, P.: Type-based Publish/Subscribe: Concepts and Experiences. TOPLAS 29(1) (2007)

[26] Navarro, L., Sudholt, M., Vanderperren, W., Fraine, B.D., Suvee, D.: Explicitly Distributed AOP usingAWED. AOSD ’06. 51–62

[27] Ericsson Computer Science Laboratory: The Erlang Pogramming Language. www.erlang.org.

[28] Reppy, J.H., Xiao, Y.: Specialization of CML Message-passing Primitives. POPL 2007. 315–326

[29] Fournet, C. , Gonthier, C.: The Reflexive Chemical Abstract Machine and the Join Calculus. POPL’96. 371–385

[30] Spring, J., Privat, J., Guerraoui, R., Vitek, J.: StreamFlex: High-Throughput Stream Programming inJava. OOPSLA 2007. 211–228

[31] Lamb, A.A., Thies, W., Amarasinghe, S.: Linear Analysis and Optimization of Stream Programs.PLDI’03. 12–25

[32] Milicia, G., Sassone, V.: Jeeg: Temporal Constraints for the Synchronization of Concurrent Objects.CCPE 17(5–6) (2005) 539–572

[33] Briot, J.P.: Actalk: A Testbed for Classifying and Designing Actor Languages in the Smalltalk-80Environment. ECOOP ’89. 109–129

[34] Chin, B., Millstein, T.: Responders: Language Support for Interactive Applications. ECOOP 2006.255–278

[35] Lin, C., Black, A.P.: DirectFlow: A Domain-Specific Language for Information-Flow Systems. ECOOP2007. 299–322

[36] Bierman, G., Meijer, E., Schulte, W.: The Essence of Data Access in Cω. ECOOP 2005. 287–311

[37] Wohlstadter, E., Jackson, S., Devanbu, P.: DADO: Enhancing Middleware to Support CrosscuttingFeatures in Distributed, Heterogeneous Systems. ICSE ’03. (2003) 174–186

[38] Nishizawa, M.: Remote Pointcut: A Language Construct for Distributed AOP. AOSD ’04. 7–15

[39] Rajan, H., Leavens, G.: Ptolemy: A Language with Quantified, Typed Events. ECOOP 2008. 155-179

25

Page 26: EventJava - Purdue University

Appendix A

For means of comparison, Figure 18 sketches a possible Java implementation of the correlation pattern de-scribed in Section 2.2. This implementation reifies events as objects (classes EarningsReport and AnalystDowngrade),and stores those in EReportStore and ADowngradeStore respectively. The programmer has to choose datastructures for this. On receiving an event, the method filterAndInsert() can filter out unwanted events,and add others to the store. Then the matchAndDispatch() method finds events that match the patternand dispatches the reaction. Filtering and matching are spawned off as threads to increase throughput (thesendEvent method call returns quickly). The burden of explicitly handling threading, synchronization (inthe event store), storage, indexing, and retrieval of events falls on the programmer. In addition, he/she hasto write code to manage groups and broadcast events (not shown here due to space constraints). Recallthat a separate matchAndDispatch() method would be needed for each pattern, because the involved eventsand predicates differ. This example can of course be implemented in many other ways, for example withSQL queries or the Java Persistence API. These however only handle storage and matching; other issues likebroadcasting remain.

26

Page 27: EventJava - Purdue University

class StockMonitor {EReportStore eRStore = new EReportStore();ADowngradeStore aDStore = new ADowngradeStore();static final ExecutorService exec = Executors.newFixedThreadPool(5);Portfolio p;class ADowngradeStore {void insert(AnalystDowngrade aD)

{ //Programmer must implement operations on data structure to store events }void getByFirm(String firm) { /* Retrieval too */ }}

}class EReportStore { void insert(EarningsReport eR) { /* dito */ } }class EarningsReport {

long time;String firm;float epsEst;float epsAct;String period;

}class AnalystDowngrade {

long time;String firm1;String analyst;String from;String to;

}void reaction(EarningsReport eR, AnalystDowngrade aD) {Runnable task = new Runnable(){ public void run() { p.RecommendSell(eR.firm); } };

exec.submit(task);}void sendEvent(String eventName, Object ev) {

filterAndInsert(eventName,ev);}void matchAndDispatch() {

for(EarningsReport eR : eRStore.getValues()){AnalystDowngrade aD = aDStore.getByFirm(eR.firm);if(eR.time < aD.time) reaction(eR,aD);

}}void filterAndInsert(final String eventName, final Object ev) {Runnable task = new Runnable() {public void run() {if (eventName.equals("earningsReport")) {

EarningsReport e = (EarningsReport) ev;if (e.epsAct < e.epsEst) { //filter out unwanted eventseRStore.insert(e);matchAndDispatch();

}}if (eventName.equals("analystDowngrade")) {

AnalystDowngrade e = (AnalystDowngrade) ev;if (e.to.equals("Hold")) { //filter out unwanted eventsaDStore.insert(e);matchAndDispatch();

}}

}};exec.submit(task);

}}

Figure 18: Skeleton of plain Java implementation of the correlation pattern in Section 2.2

27