/** * This file is part of Waarp Project. * * Copyright 2009, Frederic Bregier, and individual contributors by the @author tags. See the * COPYRIGHT.txt in the distribution for a full listing of individual contributors. * * All Waarp Project is free software: you can redistribute it and/or modify it under the terms of * the GNU General Public License as published by the Free Software Foundation, either version 3 of * the License, or (at your option) any later version. * * Waarp is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General * Public License for more details. * * You should have received a copy of the GNU General Public License along with Waarp . If not, see * <http://www.gnu.org/licenses/>. */ package org.waarp.openr66.commander; import java.util.concurrent.ArrayBlockingQueue; import java.util.concurrent.BlockingQueue; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.ScheduledFuture; import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; import org.waarp.common.database.data.AbstractDbData.UpdatedInfo; import org.waarp.common.database.exception.WaarpDatabaseNoConnectionException; import org.waarp.common.database.exception.WaarpDatabaseSqlException; import org.waarp.common.logging.WaarpLogger; import org.waarp.common.logging.WaarpLoggerFactory; import org.waarp.common.utility.WaarpThreadFactory; import org.waarp.openr66.database.DbConstant; import org.waarp.openr66.database.data.DbTaskRunner; import org.waarp.openr66.protocol.configuration.Configuration; import org.waarp.openr66.protocol.networkhandler.NetworkTransaction; /** * This class launch and control the Commander and enable TaskRunner job submissions * * @author Frederic Bregier * */ public class InternalRunner { /** * Internal Logger */ private static final WaarpLogger logger = WaarpLoggerFactory .getLogger(InternalRunner.class); private final ScheduledExecutorService scheduledExecutorService; private ScheduledFuture<?> scheduledFuture; private CommanderInterface commander = null; private volatile boolean isRunning = true; private final ThreadPoolExecutor threadPoolExecutor; private final NetworkTransaction networkTransaction; /** * Create the structure to enable submission by database * * @throws WaarpDatabaseNoConnectionException * @throws WaarpDatabaseSqlException */ public InternalRunner() throws WaarpDatabaseNoConnectionException, WaarpDatabaseSqlException { if (DbConstant.admin.isActive()) { commander = new Commander(this, true); } else { commander = new CommanderNoDb(this, true); } scheduledExecutorService = Executors.newSingleThreadScheduledExecutor(new WaarpThreadFactory("InternalRunner")); isRunning = true; BlockingQueue<Runnable> workQueue = new ArrayBlockingQueue<Runnable>(10); threadPoolExecutor = new ThreadPoolExecutor(10, Configuration.configuration.getRUNNER_THREAD(), 1000, TimeUnit.MILLISECONDS, workQueue); scheduledFuture = scheduledExecutorService.scheduleWithFixedDelay(commander, Configuration.configuration.getDelayCommander(), Configuration.configuration.getDelayCommander(), TimeUnit.MILLISECONDS); networkTransaction = new NetworkTransaction(); } public NetworkTransaction getNetworkTransaction() { return networkTransaction; } /** * Submit a task * * @param taskRunner */ public void submitTaskRunner(DbTaskRunner taskRunner) { if (isRunning || !Configuration.configuration.isShutdown()) { if (threadPoolExecutor.getActiveCount() > Configuration.configuration.getRUNNER_THREAD()) { // too many current active threads taskRunner.changeUpdatedInfo(UpdatedInfo.TOSUBMIT); taskRunner.forceSaveStatus(); return; } logger.debug("Will run {}", taskRunner); ClientRunner runner = new ClientRunner(networkTransaction, taskRunner, null); if (taskRunner.isSendThrough() && (taskRunner.isRescheduledTransfer() || taskRunner.isPreTaskStarting())) { runner.setSendThroughMode(); taskRunner.checkThroughMode(); } runner.setDaemon(true); // create the client, connect and run threadPoolExecutor.execute(runner); runner = null; } } /** * First step while shutting down the service */ public void prepareStopInternalRunner() { isRunning = false; scheduledFuture.cancel(false); scheduledExecutorService.shutdown(); threadPoolExecutor.shutdown(); } /** * This should be called when the server is shutting down, after stopping active requests if * possible. */ public void stopInternalRunner() { isRunning = false; logger.info("Stopping Commander and Runner Tasks"); scheduledFuture.cancel(false); scheduledExecutorService.shutdownNow(); threadPoolExecutor.shutdownNow(); networkTransaction.closeAll(false); } public int nbInternalRunner() { return threadPoolExecutor.getActiveCount(); } public void reloadInternalRunner() throws WaarpDatabaseNoConnectionException, WaarpDatabaseSqlException { scheduledFuture.cancel(false); if (commander != null) { commander.finalize(); } if (DbConstant.admin.isActive()) { commander = new Commander(this); } else { commander = new CommanderNoDb(this); } scheduledFuture = scheduledExecutorService.scheduleWithFixedDelay(commander, Configuration.configuration.getDelayCommander(), Configuration.configuration.getDelayCommander(), TimeUnit.MILLISECONDS); } }