Skip to content

Commit

Permalink
Use ThreadSafe Set on CancelManager to improve performance, Fix memor…
Browse files Browse the repository at this point in the history
…y leak Issue #1633
  • Loading branch information
giangianoulas authored and merks committed Apr 19, 2024
1 parent 475fcea commit 6d2994a
Show file tree
Hide file tree
Showing 2 changed files with 77 additions and 82 deletions.
Expand Up @@ -851,90 +851,93 @@ public IResultIterator execute(IEventHandler eventHandler) throws DataException

ICancellable queryCanceller = new OdaQueryCanceller(odaStatement, dataSource, session.getStopSign(), this);
this.session.getCancelManager().register(queryCanceller);

if (!session.getStopSign().isStopped()) {
long startTime = System.currentTimeMillis();
odaStatement.execute();
long endTime = System.currentTimeMillis();
if (logger.isLoggable(Level.FINE)) {
logger.log(Level.FINE, "ODA query execution time: " + (endTime - startTime)
+ " ms;\n Executed query: " + odaStatement.getEffectiveQueryText());
try {
if (!session.getStopSign().isStopped()) {
long startTime = System.currentTimeMillis();
odaStatement.execute();
long endTime = System.currentTimeMillis();
if (logger.isLoggable(Level.FINE)) {
logger.log(Level.FINE, "ODA query execution time: " + (endTime - startTime)
+ " ms;\n Executed query: " + odaStatement.getEffectiveQueryText());
}
}
}

QueryContextVisitorUtil.populateEffectiveQueryText(qcv, odaStatement.getEffectiveQueryText());
QueryContextVisitorUtil.populateEffectiveQueryText(qcv, odaStatement.getEffectiveQueryText());

logger.fine("Effective Query Text:" + odaStatement.getEffectiveQueryText());
if (queryCanceller.collectException() != null) {
if (!(queryCanceller.collectException().getCause() instanceof UnsupportedOperationException)) {
throw queryCanceller.collectException();
logger.fine("Effective Query Text:" + odaStatement.getEffectiveQueryText());
if (queryCanceller.collectException() != null) {
if (!(queryCanceller.collectException().getCause() instanceof UnsupportedOperationException)) {
throw queryCanceller.collectException();
}
}
}

ResultSet rs = null;
ResultSet rs = null;

if (design != null) {
if (canAccessResultSetByName(design)) {
try {
if (design != null) {
if (canAccessResultSetByName(design)) {
try {

rs = odaStatement.getResultSet(design.getPrimaryResultSetName());
} catch (DataException e) {
throw new DataException(ResourceConstants.ERROR_HAPPEN_WHEN_RETRIEVE_RESULTSET,
design.getPrimaryResultSetName());
}
} else if (canAccessResultSetByNumber(design)) {
try {
rs = odaStatement.getResultSet(design.getPrimaryResultSetNumber());
} catch (DataException e) {
throw new DataException(ResourceConstants.ERROR_HAPPEN_WHEN_RETRIEVE_RESULTSET,
design.getPrimaryResultSetNumber());
rs = odaStatement.getResultSet(design.getPrimaryResultSetName());
} catch (DataException e) {
throw new DataException(ResourceConstants.ERROR_HAPPEN_WHEN_RETRIEVE_RESULTSET,
design.getPrimaryResultSetName());
}
} else if (canAccessResultSetByNumber(design)) {
try {
rs = odaStatement.getResultSet(design.getPrimaryResultSetNumber());
} catch (DataException e) {
throw new DataException(ResourceConstants.ERROR_HAPPEN_WHEN_RETRIEVE_RESULTSET,
design.getPrimaryResultSetNumber());
}
}
}
}
if (rs == null && !session.getStopSign().isStopped()) {
rs = odaStatement.getResultSet();
}
if (rs == null && !session.getStopSign().isStopped()) {
rs = odaStatement.getResultSet();
}

// If we did not get a result set metadata at prepare() time, get it now
if (resultMetadata == null) {
List modelResultHints = design.getResultSetHints();
resultMetadata = rs.getMetaData();
// If we did not get a result set metadata at prepare() time, get it now
if (resultMetadata == null) {
throw new DataException(ResourceConstants.METADATA_NOT_AVAILABLE);
List modelResultHints = design.getResultSetHints();
resultMetadata = rs.getMetaData();
if (resultMetadata == null) {
throw new DataException(ResourceConstants.METADATA_NOT_AVAILABLE);
}
resultMetadata = mergeResultHint(modelResultHints, resultMetadata);
}
resultMetadata = mergeResultHint(modelResultHints, resultMetadata);
}

// Initialize CachedResultSet using the ODA result set
if (!session.getDataSetCacheManager().doesSaveToCache()) {
if (((session.getEngineContext().getMode() == DataEngineContext.DIRECT_PRESENTATION
|| session.getEngineContext().getMode() == DataEngineContext.MODE_GENERATION))
&& this.getQueryDefinition() instanceof IQueryDefinition) {
IQueryDefinition queryDefn = (IQueryDefinition) this.getQueryDefinition();

Strategy strategy = QueryExecutionStrategyUtil.getQueryExecutionStrategy(this.session, queryDefn,
queryDefn.getDataSetName() == null ? null
: ((DataEngineImpl) this.session.getEngine())
.getDataSetDesign(queryDefn.getDataSetName()));
if (strategy != Strategy.Complex) {
SimpleResultSet simpleResult = new SimpleResultSet(this, rs, resultMetadata, eventHandler,
this.getGrouping(), this.session, strategy == Strategy.SimpleLookingFoward);

return simpleResult.getResultSetIterator();
// Initialize CachedResultSet using the ODA result set
if (!session.getDataSetCacheManager().doesSaveToCache()) {
if (((session.getEngineContext().getMode() == DataEngineContext.DIRECT_PRESENTATION
|| session.getEngineContext().getMode() == DataEngineContext.MODE_GENERATION))
&& this.getQueryDefinition() instanceof IQueryDefinition) {
IQueryDefinition queryDefn = (IQueryDefinition) this.getQueryDefinition();

Strategy strategy = QueryExecutionStrategyUtil.getQueryExecutionStrategy(this.session, queryDefn,
queryDefn.getDataSetName() == null ? null
: ((DataEngineImpl) this.session.getEngine())
.getDataSetDesign(queryDefn.getDataSetName()));
if (strategy != Strategy.Complex) {
SimpleResultSet simpleResult = new SimpleResultSet(this, rs, resultMetadata, eventHandler,
this.getGrouping(), this.session, strategy == Strategy.SimpleLookingFoward);

return simpleResult.getResultSetIterator();
}
}

ri = new CachedResultSet(this, resultMetadata, rs, eventHandler, session);
} else {
ri = new CachedResultSet(this, resultMetadata, new DataSetToCache(rs, resultMetadata, session),
eventHandler, session);
}

ri = new CachedResultSet(this, resultMetadata, rs, eventHandler, session);
} else {
ri = new CachedResultSet(this, resultMetadata, new DataSetToCache(rs, resultMetadata, session),
eventHandler, session);
}
if (ri != null) {
((CachedResultSet) ri).setOdaResultSet(rs);
}

if (ri != null) {
((CachedResultSet) ri).setOdaResultSet(rs);
return ri;
} finally {
this.session.getCancelManager().deregister(queryCanceller);
}

return ri;
}

private static class OdaQueryCanceller implements ICancellable {
Expand Down
Expand Up @@ -14,43 +14,38 @@
*******************************************************************************/
package org.eclipse.birt.data.engine.impl;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.TimerTask;
import java.util.concurrent.ConcurrentHashMap;

/**
*
*/

public class CancelManager extends TimerTask {
//
private List<ICancellable> cancellableList;
private final Set<ICancellable> cancellables = ConcurrentHashMap.newKeySet();

/**
* Constructor
*/
public CancelManager() {
cancellableList = new ArrayList<>();
}

/**
*
* @param cancellable
*/
public void register(ICancellable cancellable) {
synchronized (cancellableList) {
cancellableList.add(cancellable);
}
cancellables.add(cancellable);
}

/**
*
* @param cancellable
*/
public void deregister(ICancellable cancellable) {
synchronized (cancellableList) {
cancellableList.remove(cancellable);
}
cancellables.remove(cancellable);
}

/*
Expand All @@ -64,12 +59,9 @@ public void run() {
}

public void doCancel() {
synchronized (cancellableList) {
List<ICancellable> cancellableLists = new ArrayList<>(cancellableList);
for (ICancellable cancellable : cancellableLists) {
if (cancellable.doCancel()) {
cancellable.cancel();
}
for (ICancellable cancellable : cancellables.toArray(ICancellable[]::new)) {
if (cancellable.doCancel()) {
cancellable.cancel();
}
}
}
Expand Down

0 comments on commit 6d2994a

Please sign in to comment.