-
Notifications
You must be signed in to change notification settings - Fork 27
Open
Description
Description:
Method getPercentileValue is not protected to the possibility of valueList to be empty due to event expiration. This provokes an IndexOutOfBoundsException. I am currently working on a use case where we need to compute percentiles over a sliding window and caught this situation. Currently, I am using a modified version of the extension in order cope with my requirements, but I am available to contribute it via PR.
Exception obtained:
19:13:35.621 [main] INFO io.siddhi.core.util.EventPrinter - [Event{timestamp=1000, data=[1, 10.0], isExpired=false}]
19:13:35.625 [main] INFO io.siddhi.core.util.EventPrinter - [Event{timestamp=1200, data=[1, 10.0], isExpired=false}]
19:13:35.626 [main] INFO io.siddhi.core.util.EventPrinter - [Event{timestamp=1500, data=[1, 10.0], isExpired=false}]
WARNING: sun.reflect.Reflection.getCallerClass is not supported. This will impact performance.
19:13:35.635 [main] ERROR io.siddhi.core.util.Scheduler - Error while sending timer events, Index -1 out of bounds for length 0
java.lang.IndexOutOfBoundsException: Index -1 out of bounds for length 0
at jdk.internal.util.Preconditions.outOfBounds(Preconditions.java:100) ~[?:?]
at jdk.internal.util.Preconditions.outOfBoundsCheckIndex(Preconditions.java:106) ~[?:?]
at jdk.internal.util.Preconditions.checkIndex(Preconditions.java:302) ~[?:?]
at java.util.Objects.checkIndex(Objects.java:359) ~[?:?]
at java.util.ArrayList.get(ArrayList.java:427) ~[?:?]
at io.siddhi.extension.execution.math.PercentileFunctionExtension.getPercentileValue(PercentileFunctionExtension.java:197) ~[classes/:?]
at io.siddhi.extension.execution.math.PercentileFunctionExtension.access$300(PercentileFunctionExtension.java:84) ~[classes/:?]
at io.siddhi.extension.execution.math.PercentileFunctionExtension$IntPercentileAttributeState.processRemove(PercentileFunctionExtension.java:325) ~[classes/:?]
at io.siddhi.extension.execution.math.PercentileFunctionExtension.processRemove(PercentileFunctionExtension.java:160) ~[classes/:?]
at io.siddhi.extension.execution.math.PercentileFunctionExtension.processRemove(PercentileFunctionExtension.java:50) ~[classes/:?]
at io.siddhi.core.query.selector.attribute.aggregator.AttributeAggregatorExecutor.processRemove(AttributeAggregatorExecutor.java:139) ~[siddhi-core-5.1.21.jar:?]
at io.siddhi.core.query.selector.attribute.aggregator.AttributeAggregatorExecutor.processAttributeArray(AttributeAggregatorExecutor.java:78) ~[siddhi-core-5.1.21.jar:?]
at io.siddhi.core.query.selector.attribute.aggregator.AttributeAggregatorExecutor.execute(AttributeAggregatorExecutor.java:61) ~[siddhi-core-5.1.21.jar:?]
at io.siddhi.core.query.selector.attribute.processor.AttributeProcessor.process(AttributeProcessor.java:41) ~[siddhi-core-5.1.21.jar:?]
at io.siddhi.core.query.selector.QuerySelector.processInBatchNoGroupBy(QuerySelector.java:284) ~[siddhi-core-5.1.21.jar:?]
at io.siddhi.core.query.selector.QuerySelector.process(QuerySelector.java:86) ~[siddhi-core-5.1.21.jar:?]
at io.siddhi.core.query.processor.stream.window.TimeWindowProcessor.process(TimeWindowProcessor.java:168) ~[siddhi-core-5.1.21.jar:?]
at io.siddhi.core.query.processor.stream.window.TimeWindowProcessor.process(TimeWindowProcessor.java:58) ~[siddhi-core-5.1.21.jar:?]
at io.siddhi.core.query.processor.stream.window.SlidingWindowProcessor.processEventChunk(SlidingWindowProcessor.java:74) ~[siddhi-core-5.1.21.jar:?]
at io.siddhi.core.query.processor.stream.AbstractStreamProcessor.process(AbstractStreamProcessor.java:133) ~[siddhi-core-5.1.21.jar:?]
at io.siddhi.core.query.input.stream.single.EntryValveProcessor.process(EntryValveProcessor.java:51) ~[siddhi-core-5.1.21.jar:?]
at io.siddhi.core.util.Scheduler.sendTimerEvents(Scheduler.java:196) [siddhi-core-5.1.21.jar:?]
at io.siddhi.core.util.Scheduler.access$300(Scheduler.java:49) [siddhi-core-5.1.21.jar:?]
at io.siddhi.core.util.Scheduler$1.onTimeChange(Scheduler.java:95) [siddhi-core-5.1.21.jar:?]
at io.siddhi.core.util.timestamp.TimestampGeneratorImpl.setCurrentTimestamp(TimestampGeneratorImpl.java:114) [siddhi-core-5.1.21.jar:?]
at io.siddhi.core.stream.input.InputHandler.send(InputHandler.java:76) [siddhi-core-5.1.21.jar:?]
at io.siddhi.extension.execution.math.Test.main(Test.java:43) [classes/:?]
19:13:35.666 [main] INFO io.siddhi.core.util.EventPrinter - [Event{timestamp=7000, data=[1, 10.0], isExpired=false}]
19:13:35.667 [main] INFO io.siddhi.core.util.EventPrinter - [Event{timestamp=8000, data=[1, 10.0], isExpired=false}]
19:13:35.667 [main] INFO io.siddhi.core.util.EventPrinter - [Event{timestamp=9000, data=[1, 10.0], isExpired=false}]
19:13:35.668 [main] INFO io.siddhi.core.util.EventPrinter - [Event{timestamp=11000, data=[1, 10.0], isExpired=false}]
19:13:35.668 [main] INFO io.siddhi.core.util.EventPrinter - [Event{timestamp=12000, data=[1, 10.0], isExpired=false}]
19:13:35.669 [main] INFO io.siddhi.core.util.EventPrinter - [Event{timestamp=12000, data=[1, 10.0], isExpired=false}]
Process finished with exit code 0
Affected Product Version:
5.0.4+
OS, DB, other environment details and versions:
Linux x64. OpenJDK 1.8.
Steps to reproduce:
The following code snippet can be used to reproduce the issue:
SiddhiManager siddhiManager = new SiddhiManager();
String executionPlan = ("@app:playback "
+ "define stream inputStream (sensorId int, temperature int); "
+ "partition with (sensorId of inputStream)\n"
+ "begin "
+ "@info(name = 'query1') from inputStream#window.time(5 sec) "
+ "select sensorId, math:percentile(temperature, 97.0) as percentile "
+ "insert all events into outputStream; " +
"end;");
SiddhiAppRuntime siddhiAppRuntime = siddhiManager
.createSiddhiAppRuntime(executionPlan);
siddhiAppRuntime.addCallback("outputStream", new StreamCallback() {
@Override
public void receive(Event[] events) {
EventPrinter.print(events);
}
});
InputHandler inputHandler = siddhiAppRuntime.getInputHandler("inputStream");
siddhiAppRuntime.start();
inputHandler.send(new Event(1000L,new Object[]{1, 10}));
inputHandler.send(new Event(1200L,new Object[]{1, 10}));
inputHandler.send(new Event(1500L,new Object[]{1, 10}));
inputHandler.send(new Event(7000L,new Object[]{1, 10}));
inputHandler.send(new Event(8000L,new Object[]{1, 10}));
inputHandler.send(new Event(9000L,new Object[]{1, 10}));
inputHandler.send(new Event(11000L,new Object[]{1, 10}));
inputHandler.send(new Event(12000L,new Object[]{1, 10}));
siddhiAppRuntime.shutdown();Metadata
Metadata
Assignees
Labels
No labels