Creating instances of Esper's epl

2019-08-14 03:50发布

问题:

I am playing around with Esper, learning how to use more advanced concepts. I have a program that fires mock stock events of 3 different stocks. I currently have a module with match_recognize pattern EPL that looks like this:

module queries;

import events.*;
import configDemo.*;
import annotations.*;

create schema MyTickEvent as TickEvent;

@Name('compareStocks') 
@Description('Compare the difference amount between two stocks')
@Subscriber(className='configDemo.MySubscriber')
select * from TickEvent
match_recognize (
measures A.currentPrice as a_currentPrice, B.currentPrice as b_currentPrice, 
A.stockName as a_stockName, B.stockName as b_stockName
pattern (A C* B)
define
A as A.stockName = firstStock,
B as A.currentPrice - B.currentPrice >= difference and B.stockName = 
secondStock
);

As you can see there are three variables in it - firstStock, secondStock, difference. I take the user's input and then set the variables within the java code as such:

    System.out.println("Please enter 3 char stock name for the first stock: ");
    System.out.println("Available stocks: IBM, YAH, MIC");
    first = scanner.nextLine();
    engineHelper.getAdmin().getConfiguration().addVariable("firstStock", String.class, first);

    System.out.println("Please enter 3 char stock name for the second stock: ");
    second = scanner.nextLine();
    engineHelper.getAdmin().getConfiguration().addVariable("secondStock", String.class, second);

    System.out.println("Please enter integer value for stock difference: ");
    difference = scanner.nextInt();
    engineHelper.getAdmin().getConfiguration().addVariable("difference", Integer.class, difference);

That works fine if I only want to keep track of one stock pair at a time. I am struggling to find a way of doing that for multiple pairs. I want to be able to dynamically create/delete/start/stop pairs. For examples, let's say I have YAH, APP, MIC, GOO stocks. The events start running and I decide that I want to track for a difference of more than X amount between MIC/GOO. Then I decide I want to track APP/GOO too for a different amount. The data would be something like this:

[IBM, YAH, 5] [GOO, APP, 3] ....

Any suggestions of how to do that? I imagine I would need to create a new instance of the EPL with a new set of variables. I can easily do that within java code but I want to stay away from it as much as possible. I want to use module files. Since it is essentially the same EPL, it would make sense to have a way of using it as a template with multiple "instances" for different stock pairs.

Alternatively, are there other ways of achieving this efficiently?

I got it working, I noticed the errors come from text that no longer exists in the file so I deleted it and rewrote it and it worked. All is deployed successfully now and this is how it looks:

module context;

import events.*;
import configDemo.*;
import annotations.*;
import main.*;
import subscribers.*;


create schema InitEvent(firstStock string, secondStock string, bias double);

create context TwoStocksContext
initiated by InitEvent as initEvent;


@Name('compareStocks') 
@Description('Compare the difference between two different stocks and make a 
decision')
@Subscriber(className='subscribers.MySubscriber')
context TwoStocksContext 
select * from TickEvent
match_recognize (
measures A.currentPrice as a_currentPrice, B.currentPrice as b_currentPrice, A.stockCode as a_stockCode, B.stockCode as b_stockCode
pattern (A C* B)
define
A as A.stockCode =  context.initEvent.firstStock,
B as A.currentPrice - B.currentPrice >=  context.initEvent.bias and 
B.stockCode =  context.initEvent.secondStock
);

回答1:

You can get Esper to allocate multiple partitions of a statement using contexts. Put the variables into an "Init"-Event and send this event to allocate each. An example

create schema InitEvent(firststock string, secondstock string, diff double);

create context AnalyzePerFirstAndSecond initiated by InitEvent as initEvent; // add terminated here if needed

context AnalyzePerFirstAndSecond select .... define A as A.stock = context.initEvent.firststock....

Doc chapter link for more complete solution... http://esper.espertech.com/release-7.0.0/esper-reference/html_single/index.html#perf-tips-27