/* * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. * * WSO2 Inc. licenses this file to you under the Apache License, * Version 2.0 (the "License"); you may not use this file except * in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.wso2.siddhi.core.query.output.ratelimit.time; import org.apache.log4j.Logger; import org.wso2.siddhi.core.event.ComplexEvent; import org.wso2.siddhi.core.event.ComplexEventChunk; import org.wso2.siddhi.core.event.stream.StreamEventPool; import org.wso2.siddhi.core.query.output.ratelimit.OutputRateLimiter; import org.wso2.siddhi.core.util.Schedulable; import org.wso2.siddhi.core.util.Scheduler; import org.wso2.siddhi.core.util.parser.SchedulerParser; import java.util.ArrayList; import java.util.HashMap; import java.util.Map; import java.util.concurrent.ScheduledExecutorService; /** * Implementation of {@link OutputRateLimiter} which will collect pre-defined time period and the emit all * collected events as a batch. */ public class AllPerTimeOutputRateLimiter extends OutputRateLimiter implements Schedulable { private static final Logger log = Logger.getLogger(AllPerTimeOutputRateLimiter.class); private final Long value; private String id; private ScheduledExecutorService scheduledExecutorService; private Scheduler scheduler; private ComplexEventChunk<ComplexEvent> allComplexEventChunk; private long scheduledTime; private String queryName; public AllPerTimeOutputRateLimiter(String id, Long value, ScheduledExecutorService scheduledExecutorService, String queryName) { this.id = id; this.value = value; this.queryName = queryName; this.scheduledExecutorService = scheduledExecutorService; allComplexEventChunk = new ComplexEventChunk<ComplexEvent>(false); } @Override public OutputRateLimiter clone(String key) { AllPerTimeOutputRateLimiter instance = new AllPerTimeOutputRateLimiter(id + key, value, scheduledExecutorService, queryName); instance.setLatencyTracker(latencyTracker); return instance; } @Override public void process(ComplexEventChunk complexEventChunk) { ArrayList<ComplexEventChunk<ComplexEvent>> outputEventChunks = new ArrayList<ComplexEventChunk<ComplexEvent>>(); complexEventChunk.reset(); synchronized (this) { while (complexEventChunk.hasNext()) { ComplexEvent event = complexEventChunk.next(); if (event.getType() == ComplexEvent.Type.TIMER) { if (event.getTimestamp() >= scheduledTime) { ComplexEvent first = allComplexEventChunk.getFirst(); if (first != null) { allComplexEventChunk.clear(); ComplexEventChunk<ComplexEvent> outputEventChunk = new ComplexEventChunk<ComplexEvent> (complexEventChunk.isBatch()); outputEventChunk.add(first); outputEventChunks.add(outputEventChunk); } scheduledTime = scheduledTime + value; scheduler.notifyAt(scheduledTime); } } else if (event.getType() == ComplexEvent.Type.CURRENT || event.getType() == ComplexEvent.Type .EXPIRED) { complexEventChunk.remove(); allComplexEventChunk.add(event); } } } for (ComplexEventChunk eventChunk : outputEventChunks) { sendToCallBacks(eventChunk); } } @Override public void start() { scheduler = SchedulerParser.parse(scheduledExecutorService, this, executionPlanContext); scheduler.setStreamEventPool(new StreamEventPool(0, 0, 0, 5)); scheduler.init(lockWrapper, queryName); long currentTime = System.currentTimeMillis(); scheduledTime = currentTime + value; scheduler.notifyAt(scheduledTime); } @Override public void stop() { //Nothing to stop } @Override public Map<String, Object> currentState() { Map<String, Object> state = new HashMap<>(); state.put("AllComplexEventChunk", allComplexEventChunk.getFirst()); return state; } @Override public void restoreState(Map<String, Object> state) { allComplexEventChunk.clear(); allComplexEventChunk.add((ComplexEvent) state.get("AllComplexEventChunk")); } }