Skip to content
Tim Olson edited this page Feb 7, 2015 · 2 revisions

Context

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 binding

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.

Module Esper Files

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) { /**/ }
}

Services

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.

Clone this wiki locally