com.espertech.esper.runtime.internal.kernel.service.StatementResultServiceImpl Maven / Gradle / Ivy
The newest version!
/*
***************************************************************************************
* Copyright (C) 2006 EsperTech, Inc. All rights reserved. *
* http://www.espertech.com/esper *
* http://www.espertech.com *
* ---------------------------------------------------------------------------------- *
* The software in this package is published under the terms of the GPL license *
* a copy of which has been included with this distribution in the license.txt file. *
***************************************************************************************
*/
package com.espertech.esper.runtime.internal.kernel.service;
import com.espertech.esper.common.client.EventBean;
import com.espertech.esper.common.internal.collection.UniformPair;
import com.espertech.esper.common.internal.context.module.StatementInformationalsRuntime;
import com.espertech.esper.common.internal.context.util.StatementContext;
import com.espertech.esper.common.internal.context.util.StatementDispatchTLEntry;
import com.espertech.esper.common.internal.context.util.StatementResultService;
import com.espertech.esper.common.internal.epl.expression.core.ExprEvaluator;
import com.espertech.esper.common.internal.event.core.EventBeanUtility;
import com.espertech.esper.common.internal.event.core.NaturalEventBean;
import com.espertech.esper.common.internal.metrics.stmtmetrics.StatementMetricHandle;
import com.espertech.esper.runtime.client.EPSubscriberException;
import com.espertech.esper.runtime.client.UpdateListener;
import com.espertech.esper.runtime.internal.kernel.statement.EPStatementListenerSet;
import com.espertech.esper.runtime.internal.kernel.statement.EPStatementSPI;
import com.espertech.esper.runtime.internal.kernel.thread.OutboundUnitRunnable;
import com.espertech.esper.runtime.internal.metrics.instrumentation.InstrumentationHelper;
import com.espertech.esper.runtime.internal.subscriber.ResultDeliveryStrategy;
import com.espertech.esper.runtime.internal.subscriber.ResultDeliveryStrategyFactory;
import com.espertech.esper.runtime.internal.subscriber.ResultDeliveryStrategyInvalidException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.*;
/**
* Implements tracking of statement listeners and subscribers for a given statement
* such as to efficiently dispatch in situations where 0, 1 or more listeners
* are attached and/or 0 or 1 subscriber (such as iteration-only statement).
*/
public class StatementResultServiceImpl implements StatementResultService {
private final static Logger log = LoggerFactory.getLogger(StatementResultServiceImpl.class);
private final StatementInformationalsRuntime statementInformationals;
private final EPServicesContext epServicesContext;
private final boolean outboundThreading;
// Part of the statement context
private EPStatementSPI epStatement;
private EPRuntimeSPI runtime;
private StatementMetricHandle statementMetricHandle;
private boolean forClauseDelivery = false;
private ExprEvaluator groupDeliveryExpressions;
// For natural delivery derived out of select-clause expressions
private Class[] selectClauseTypes;
private String[] selectClauseColumnNames;
// Listeners and subscribers and derived information
private EPStatementListenerSet statementListenerSet;
private boolean isMakeNatural;
private boolean isMakeSynthetic;
private ResultDeliveryStrategy statementResultNaturalStrategy;
/**
* Buffer for holding dispatchable events.
*/
protected ThreadLocal statementDispatchTL = new ThreadLocal() {
protected synchronized StatementDispatchTLEntry initialValue() {
return new StatementDispatchTLEntry();
}
};
public StatementResultServiceImpl(StatementInformationalsRuntime statementInformationals,
EPServicesContext epServicesContext) {
this.statementInformationals = statementInformationals;
this.epServicesContext = epServicesContext;
this.outboundThreading = epServicesContext.getThreadingService().isOutboundThreading();
isMakeSynthetic = statementInformationals.isAlwaysSynthesizeOutputEvents();
}
public void setContext(EPStatementSPI epStatement, EPRuntimeSPI runtime) {
this.epStatement = epStatement;
this.runtime = runtime;
this.statementMetricHandle = epStatement.getStatementContext().getEpStatementHandle().getMetricsHandle();
}
public void setSelectClause(Class[] selectClauseTypes, String[] selectClauseColumnNames,
boolean forClauseDelivery, ExprEvaluator groupDeliveryExpressions) {
this.selectClauseTypes = selectClauseTypes;
this.selectClauseColumnNames = selectClauseColumnNames;
this.forClauseDelivery = forClauseDelivery;
this.groupDeliveryExpressions = groupDeliveryExpressions;
}
public ThreadLocal getDispatchTL() {
return statementDispatchTL;
}
public int getStatementId() {
return epStatement.getStatementContext().getStatementId();
}
public boolean isMakeSynthetic() {
return isMakeSynthetic;
}
public boolean isMakeNatural() {
return isMakeNatural;
}
public String getStatementName() {
return epStatement.getName();
}
public EPStatementListenerSet getStatementListenerSet() {
return statementListenerSet;
}
public void setUpdateListeners(EPStatementListenerSet updateListeners, boolean isRecovery) {
// indicate that listeners were updated for potential persistence of listener set, once the statement context is known
if (epStatement != null) {
if (!isRecovery) {
StatementContext stmtCtx = epStatement.getStatementContext();
epServicesContext.getEpServicesHA().getListenerRecoveryService().put(stmtCtx.getStatementId(), stmtCtx.getStatementName(), updateListeners.getListeners());
}
}
this.statementListenerSet = updateListeners;
isMakeNatural = statementListenerSet.getSubscriber() != null;
isMakeSynthetic = !(statementListenerSet.getListeners().length == 0) || statementInformationals.isAlwaysSynthesizeOutputEvents();
if (statementListenerSet.getSubscriber() == null) {
statementResultNaturalStrategy = null;
isMakeNatural = false;
return;
}
try {
statementResultNaturalStrategy = ResultDeliveryStrategyFactory.create(epStatement, statementListenerSet.getSubscriber(), statementListenerSet.getSubscriberMethodName(),
selectClauseTypes, selectClauseColumnNames, runtime.getURI(), runtime.getServicesContext().getClasspathImportServiceRuntime());
isMakeNatural = true;
} catch (ResultDeliveryStrategyInvalidException ex) {
throw new EPSubscriberException(ex.getMessage(), ex);
}
}
// Called by OutputProcessView
public void indicate(UniformPair results, StatementDispatchTLEntry dispatchTLEntry) {
if (results != null) {
if (statementMetricHandle.isEnabled()) {
int numIStream = (results.getFirst() != null) ? results.getFirst().length : 0;
int numRStream = (results.getSecond() != null) ? results.getSecond().length : 0;
epServicesContext.getMetricReportingService().accountOutput(statementMetricHandle, numIStream, numRStream, epStatement, runtime);
}
ArrayDeque> lastResults = dispatchTLEntry.getResults();
if ((results.getFirst() != null) && (results.getFirst().length != 0)) {
lastResults.add(results);
} else if ((results.getSecond() != null) && (results.getSecond().length != 0)) {
lastResults.add(results);
}
}
}
public void execute(StatementDispatchTLEntry dispatchTLEntry) {
ArrayDeque> dispatches = dispatchTLEntry.getResults();
UniformPair events = EventBeanUtility.flattenList(dispatches);
if (InstrumentationHelper.ENABLED) {
InstrumentationHelper.get().qStatementResultExecute(events, epStatement.getDeploymentId(), epStatement.getStatementId(), epStatement.getName(), Thread.currentThread().getId());
InstrumentationHelper.get().aStatementResultExecute();
}
if (outboundThreading) {
epServicesContext.getThreadingService().submitOutbound(new OutboundUnitRunnable(events, this));
} else {
processDispatch(events);
}
dispatches.clear();
}
/**
* Indicate an outbound result.
*
* @param events to indicate
*/
public void processDispatch(UniformPair events) {
// Plain all-events delivery
if (!forClauseDelivery) {
dispatchInternal(events);
return;
}
// Discrete delivery
if (groupDeliveryExpressions == null) {
UniformPair todeliver = new UniformPair(null, null);
if (events != null) {
if (events.getFirst() != null) {
for (EventBean theEvent : events.getFirst()) {
todeliver.setFirst(new EventBean[]{theEvent});
dispatchInternal(todeliver);
}
todeliver.setFirst(null);
}
if (events.getSecond() != null) {
for (EventBean theEvent : events.getSecond()) {
todeliver.setSecond(new EventBean[]{theEvent});
dispatchInternal(todeliver);
}
todeliver.setSecond(null);
}
}
return;
}
// Grouped delivery
Map
© 2015 - 2025 Weber Informatics LLC | Privacy Policy