All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.databene.task.runner.PagedTaskRunner Maven / Gradle / Ivy

Go to download

benerator is a framework for creating realistic and valid high-volume test data, used for testing (unit/integration/load) and showcase setup. Metadata constraints are imported from systems and/or configuration files. Data can imported from and exported to files and systems, anonymized or generated from scratch. Domain packages provide reusable generators for creating domain-specific data as names and addresses internationalizable in language and region. It is strongly customizable with plugins and configuration options.

There is a newer version: 0.9.8
Show newest version
/*
 * (c) Copyright 2007-2011 by Volker Bergmann. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, is permitted under the terms of the
 * GNU General Public License.
 *
 * For redistributing this software or a derivative work under a license other
 * than the GPL-compatible Free Software License as defined by the Free
 * Software Foundation or approved by OSI, you must first obtain a commercial
 * license to this software product from Volker Bergmann.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * WITHOUT A WARRANTY OF ANY KIND. ALL EXPRESS OR IMPLIED CONDITIONS,
 * REPRESENTATIONS AND WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE
 * HEREBY EXCLUDED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */

package org.databene.task.runner;

import org.databene.commons.Context;
import org.databene.commons.ErrorHandler;
import org.databene.commons.Expression;
import org.databene.commons.context.DefaultContext;
import org.databene.commons.expression.ExpressionUtil;
import org.databene.contiperf.PerformanceTracker;
import org.databene.platform.contiperf.PerfTrackingTaskProxy;
import org.databene.task.PageListener;
import org.databene.task.StateTrackingTaskProxy;
import org.databene.task.Task;
import org.databene.task.TaskUnavailableException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.PrintWriter;
import java.util.List;
import java.util.concurrent.ExecutorService;

/**
 * {@link TaskRunner} implementation that provides for repeated, paged, 
 * multi- or single-threaded Task execution.

* Created: 16.07.2007 19:25:30 * @author Volker Bergmann */ public class PagedTaskRunner extends AbstractTaskRunner implements Thread.UncaughtExceptionHandler { private static final Logger logger = LoggerFactory.getLogger(PagedTaskRunner.class); private List pageListeners; private long pageSize; private int threadCount; private Expression executor; private PerformanceTracker tracker; private Throwable exception; // constructors ---------------------------------------------------------------------------------------------------- public PagedTaskRunner(Task target, List listeners, long pageSize, int threads, boolean stats, ExecutorService executor) { this(target, listeners, pageSize, threads, stats, ExpressionUtil.constant(executor), new DefaultContext(), ErrorHandler.getDefault()); } public PagedTaskRunner(Task target, List pageListeners, long pageSize, int threads, boolean stats, Expression executor, Context context, ErrorHandler errorHandler) { super(null, context, errorHandler); // call super constructor without target... if (stats) { target = new PerfTrackingTaskProxy(target); this.tracker = ((PerfTrackingTaskProxy) target).getTracker(); } this.target = new StateTrackingTaskProxy(target); // ...but provide it afterwards this.pageListeners = pageListeners; this.pageSize = pageSize; this.threadCount = threads; this.executor = executor; } // Task implementation --------------------------------------------------------------------------------------------- public long getPageSize() { return pageSize; } public int getThreadCount() { return threadCount; } public long run(Long requestedInvocations, Long minInvocations) { // first run without verification long countValue = run(requestedInvocations); // afterwards verify execution count if (minInvocations != null && countValue < minInvocations) throw new TaskUnavailableException(target, minInvocations, countValue); if (tracker != null) tracker.getCounter().printSummary(new PrintWriter(System.out), 90, 95); return countValue; } public long run(Long invocationCount) { if (invocationCount != null && invocationCount == 0) return 0; long queuedInvocations = 0; long queuedPages = 0; long actualCount = 0; if (invocationCount != null) { if (pageSize > 0) queuedPages = (invocationCount + pageSize - 1) / pageSize; queuedInvocations = invocationCount; } this.exception = null; if (logger.isDebugEnabled()) logger.debug("Running PagedTask[" + getTaskName() + "]"); int currentPageNo = 0; TaskRunner pageRunner; if (threadCount == 1) pageRunner = new SingleThreadedTaskRunner(target, (pageSize > 0), context, errorHandler); else pageRunner = new MultiThreadedTaskRunner(target, threadCount, context, executor.evaluate(context), errorHandler, tracker); // TODO v1.0 avoid pageFinished when pageSize == 0 do { try { if (pageSize > 0) pageStarting(currentPageNo); long currentPageSize; if (pageSize > 0) currentPageSize = (invocationCount == null ? pageSize : Math.min(pageSize, queuedInvocations)); else currentPageSize = (invocationCount == null ? 1 : Math.min(invocationCount, queuedInvocations)); queuedInvocations -= currentPageSize; long localCount = pageRunner.run(currentPageSize); actualCount += localCount; if (invocationCount != null) queuedPages--; if (pageSize > 0) pageFinished(currentPageNo, context); if (exception != null) throw new RuntimeException(exception); currentPageNo++; } catch (Exception e) { errorHandler.handleError("Error in execution of task " + getTaskName(), e); } } while (workPending(invocationCount, queuedPages)); if (logger.isDebugEnabled()) logger.debug("PagedTask " + getTaskName() + " finished"); return actualCount; } public String getTaskName() { return target.getTaskName(); } public static PerformanceTracker execute(Task task, Context context, Long requestedInvocations, Long minInvocations, List pageListeners, long pageSize, int threadCount, boolean stats, ExecutorService executorService, ErrorHandler errorHandler, boolean infoLog) { logExecutionInfo(task, requestedInvocations, minInvocations, pageSize, threadCount, infoLog); PagedTaskRunner pagedTask = new PagedTaskRunner(task, pageListeners, pageSize, threadCount, stats, ExpressionUtil.constant(executorService), context, errorHandler); pagedTask.run(requestedInvocations, minInvocations); return pagedTask.tracker; } // non-public helpers ---------------------------------------------------------------------------------------------- @SuppressWarnings("unchecked") protected boolean workPending(Long maxInvocationCount, long queuedPages) { if (!((StateTrackingTaskProxy) target).isAvailable()) return false; if (maxInvocationCount == null) return true; return (queuedPages > 0); } protected void pageStarting(int currentPageNo) { if (logger.isDebugEnabled()) logger.debug("Starting page " + (currentPageNo + 1) + " of " + getTaskName() + " with pageSize=" + pageSize); if (pageListeners != null) for (PageListener listener : pageListeners) listener.pageStarting(); } protected void pageFinished(int currentPageNo, Context context) { if (logger.isDebugEnabled()) logger.debug("Page " + (currentPageNo + 1) + " of " + getTaskName() + " finished"); if (pageListeners != null) for (PageListener listener : pageListeners) listener.pageFinished(); } private static void logExecutionInfo(Task task, Long minInvocations, Long maxInvocations, long pageSize, int threadCount, boolean infoLog) { if (infoLog) { if (logger.isInfoEnabled()) { String invocationInfo = executionInfo(task, minInvocations, maxInvocations, pageSize, threadCount); logger.info(invocationInfo); } } else if (logger.isDebugEnabled()) { String invocationInfo = executionInfo(task, minInvocations, maxInvocations, pageSize, threadCount); logger.debug(invocationInfo); } } private static String executionInfo(Task task, Long minInvocations, Long maxInvocations, long pageSize, int threadCount) { String invocationInfo = (maxInvocations == null ? "as long as available" : (maxInvocations > 1 ? maxInvocations + " times" : "")); if (minInvocations != null && minInvocations > 0 && (maxInvocations == null || maxInvocations > minInvocations)) invocationInfo += " requiring at least " + minInvocations + " generations"; if (invocationInfo.length() > 0) invocationInfo += " with page size " + pageSize + " in " + (threadCount > 1 ? threadCount + " threads" : "a single thread"); return "Running task " + task + " " + invocationInfo; } public void uncaughtException(Thread t, Throwable e) { this.exception = e; } @Override public String toString() { return getClass().getSimpleName(); } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy