如果启用了入站线程池,我发现Esper(v.7.1.0)中的数据丢失。这是演示这种奇怪行为的简单示例:
Configuration config = new Configuration();
// set up concurrent processing
config.getEngineDefaults().getThreading().setThreadPoolInbound(true);
EPServiceProvider epService = EPServiceProviderManager.getDefaultProvider(config);
// simple schema
epService.getEPAdministrator().createEPL("create objectarray schema LogLine as (account_name string, value int) ");
// event for terminating context partition
epService.getEPAdministrator().createEPL("create schema TerminateEvent() ");
// Allocates context partition for each account_name. Start it on LogLine event and terminate on TerminateEvent.
epService.getEPAdministrator()
.createEPL("create context NestedCtx " +
"context InitCtx start LogLine end TerminateEvent ," +
"context AccountCtx partition by account_name from LogLine");
// select to collect count of events per account_name.
EPStatement statement = epService.getEPAdministrator().createEPL(" context NestedCtx select account_name, count(*) as total from LogLine output last when terminated ");
// attach listener for printing results
statement.addListener(new UpdateListener() {
@Override
public void update(EventBean[] newEvents, EventBean[] oldEvents) {
for (EventBean eventBean : newEvents) {
String properties = Arrays.stream(eventBean.getEventType().getPropertyNames()).map((prop) -> {
return prop + " " + eventBean.get(prop);
}).collect(Collectors.joining("; "));
System.out.println(properties);
}
}
});
//send 3 LogLine events
epService.getEPRuntime().sendEvent(new Object[] { "TEST", 10 }, "LogLine");
epService.getEPRuntime().sendEvent(new Object[] { "TEST", 10 }, "LogLine");
epService.getEPRuntime().sendEvent(new Object[] { "TEST", 10 }, "LogLine");
// send terminate event in order to get results
epService.getEPRuntime().sendEvent(Collections.emptyMap(), "TerminateEvent");
System.out.println("finish");
问题是启用并发处理时不会调用UpdateListener。仅在禁用入站线程池时才打印结果。 这种行为的原因是什么?
答案 0 :(得分:1)
入站线程可以更改事件处理的顺序,因为JVM可以按任何顺序处理排队的任务。因此,当您的用例需要有序处理事件时,这意味着入站线程不是正确的选择。您的应用程序代码可以改为分配您的队列/线程并将事件关联到线程,以确保保留订单。例如as discussed in this StackOverflow question.