-
Notifications
You must be signed in to change notification settings - Fork 166
The Context Class
The center of the Coin Trader architecture is Context
, which is a scope: it combines an Esper engine instance, an Injector, and a Configuration. Any Java class may be passed to Context.attach(myClass.class,myConfig)
, causing the Context
to instantiate the class using the Injector and bind the instance's @When methods. Furthermore, if the class implements any interfaces which have the @Service annotation (i.e. class MockOrderService implements OrderService
and @Service interface OrderService
), then the newly attached instance will be injected into subsequently attached classes. This needs more refactoring to conform to the way Guice works with Modules.
For example, the code for SaveDataRunMode
looks like this:
public void run() {
Context context = Context.create();
context.attach(XchangeData.class);
context.attach(SaveMarketData.class);
}
XchangeData
polls the exchanges and publishes events to the Context
:
@Inject private Context context;
/*...*/
context.publish(ourTrade);
Then SaveMarketData
triggers on any MarketData
events and calls PersistUtil.insert()
. See the @When
section below:
When a class is attached to a Context
, it has an instance created using the Context
's Injector
, and any method on this instance which uses the @When
annotation will be triggered for every Event
row which triggers that @When
clause, like this:
@Singleton
public class SaveMarketData {
@When("select * from MarketData")
public void handleMarketData( MarketData m ) {
PersistUtil.insert(m);
}
}
The @When
clause may be any valid Esper statement, and the binding expects one method argument for each column in the result set.
When a module class is loaded, the Context
searches the class path for a resource which has the same base filename as the module class but with an extension of .epl
. If such a file exists, the Context
will load it as an Esper EPL file. Any EPL statements which carry the @IntoMethod
annotation will be bound to the module class's method by the same name. For example:
/org/foo/MyModuleName.epl
@IntoMethod("setAveragePrice")
select avg(priceAsDouble), count(*) from Tick
Will invoke this method on the Java module class of the same name:
/org/foo/MyModuleName.java
public class MyModuleName {
public void setAveragePrice(double price, int count) { /**/ }
}
When a class is attached to a Context
, the Context
looks at all the implemented interfaces of that class. If any of those interfaces are tagged with the @Service
annotation, then the Context
creates an Injector
binding from the service interface type to the specific instance attached to the Context
. For example, after the MockOrderService
is attached to a Context
, any subsequent classes which have a field @Inject OrderService svc;
will be populated with the specific instance of MockOrderService
which services that Context
. This is because OrderService
is tagged with @Service
.