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

com.jpattern.batch.core.ThreadJobPool Maven / Gradle / Ivy

package com.jpattern.batch.core;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.TreeMap;
import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicBoolean;

import com.jpattern.batch.Job;
import com.jpattern.batch.JobExecutor;
import com.jpattern.batch.JobExecutionStrategy;
import com.jpattern.batch.JobPool;
import com.jpattern.batch.JobStatus;
import com.jpattern.batch.logger.JobPoolLogger;
import com.jpattern.logger.ILogger;

/**
 * 
 * @author Francesco Cina'
 *
 * 29/mar/2010
 */
public class ThreadJobPool implements JobPool {

	private static final long serialVersionUID = 1L;
	private final Map> executableJobMap = new TreeMap>();
	private boolean shutdown = false;
	private final AtomicBoolean serverStarted = new AtomicBoolean( false );
	private final String name;
	private final ILogger logger = JobPoolLogger.getLogger(this.getClass());

	public ThreadJobPool(final String applicationName) {
		this.name = applicationName;
		this.logger.info("JobPool [" + applicationName + "] created");
	}

	@Override
	public void addJob(final Job job, final JobExecutionStrategy jobExecutionStrategy) {
		this.logger.info("JobPool [" + this.name + "]: adding new job; name [" + job.getName() + "] group [" + job.getGroup() + "]");
		final CallableJobExecutor executableJob = new CallableJobExecutor(job, jobExecutionStrategy, this.serverStarted );
		Executors.newSingleThreadExecutor().submit( executableJob );
		this.registerJob( job.getName() , job.getGroup(), executableJob );
	}

	private void registerJob(final String name, final String group, final JobExecutor executableJob) {
		if (!this.executableJobMap.containsKey(group)) {
			this.executableJobMap.put(group, new TreeMap());
		}
		this.executableJobMap.get(group).put(name, executableJob);
	}

	@Override
	public JobStatus getJobStatus(final String jobName, final String groupName) {
		return this.getJobExecutor(jobName, groupName).getJobStatus();
	}

	private JobExecutor getJobExecutor(final String jobName, final String groupName) {
		if (this.executableJobMap.containsKey(groupName)) {
			final Map group = this.executableJobMap.get(groupName);
			if ( group.containsKey(jobName) ) {
				return group.get(jobName);
			}
		}
		return new NullJobExecutor();
	}

	@Override
	public List getJobsName(final String groupName) {
		final List result = new ArrayList();
		if (this.executableJobMap.containsKey(groupName)) {
			final Map group = this.executableJobMap.get(groupName);
			for( final Entry jobEntry : group.entrySet() ) {
				result.add( jobEntry.getKey() );
			}
		}
		return result;
	}

	@Override
	public List getGroupsName() {
		final List result = new ArrayList();
		for( final Entry> jobEntry : this.executableJobMap.entrySet() ) {
			result.add( jobEntry.getKey() );
		}
		return result;
	}

	@Override
	public boolean isStarted() {
		return this.serverStarted.get();
	}

	@Override
	public void modifyJobExecution(final String jobName, final String groupName, final JobExecutionStrategy jobExecutionStrategy) {
		this.getJobExecutor(jobName, groupName).setExecutionStrategy(jobExecutionStrategy);
	}

	@Override
	public void pauseJob(final String jobName, final String groupName) {
		this.logger.info("JobPool [" + this.name + "]: pause job name [" + jobName + "] group [" + groupName + "]");
		this.getJobExecutor(jobName, groupName).pause();
	}

	@Override
	public void pauseGroup(final String groupName) {
		this.logger.info("JobPool [" + this.name + "]: pause group [" + groupName + "]");
		for( final String jobName : this.getJobsName(groupName) ) {
			this.pauseJob(jobName, groupName);
		}
	}

	@Override
	public void pauseAllJobs() {
		this.logger.info("JobPool [" + this.name + "]: pause all jobs");
		for( final String groupName : this.getGroupsName() ) {
			this.pauseGroup(groupName);
		}
	}

	@Override
	public void resumeJob(final String jobName, final String groupName) {
		this.logger.info("JobPool [" + this.name + "]: resume job name [" + jobName + "] group [" + groupName + "]");
		this.getJobExecutor(jobName, groupName).resume();
	}

	@Override
	public void resumeGroup(final String groupName) {
		this.logger.info("JobPool [" + this.name + "]: resume group [" + groupName + "]");
		for( final String jobName : this.getJobsName(groupName) ) {
			this.resumeJob(jobName, groupName);
		}
	}

	@Override
	public void resumeAllJobs() {
		this.logger.info("JobPool [" + this.name + "]: resume all jobs");
		for( final String groupName : this.getGroupsName() ) {
			for( final String jobName : this.getJobsName(groupName) ) {
				this.resumeJob(jobName, groupName);
			}
		}
	}

	@Override
	public void shutdown(final boolean waitJobsExecutionEnd) {
		if (!this.shutdown){
			this.logger.info("JobPool [" + this.name +  "]: Begin engine shutdown... ");
			this.serverStarted.set(false);
			for( final String groupName : this.getGroupsName() ) {
				for( final String jobName : this.getJobsName(groupName) ) {
					this.getJobExecutor(jobName, groupName).kill();
				}
			}
			if (waitJobsExecutionEnd) {
				this.logger.info("JobPool [" + this.name +  "]: Waiting job executions end... ");
				boolean allExecutionEnded = false;
				while (!allExecutionEnded) {
					allExecutionEnded = true;
					for (final String groupName : this.getGroupsName() ) {
						for(final String jobName : this.getJobsName(groupName)) {
							if ( this.getJobStatus(jobName, groupName).isRunning()) {
								allExecutionEnded = false;
							}
						}
					}
					try {
						Thread.sleep(100);
					} catch (final InterruptedException e) {
						e.printStackTrace();
					}
				}
				this.logger.info("JobPool [" + this.name +  "]: Job executions ended ");
			}
			this.shutdown = true;
			this.logger.info("JobPool [" + this.name +  "]: Shutdown engine finished.");
		}
	}

	@Override
	public void start() {
		if (this.shutdown) {
			throw new RuntimeException("JobPool [" + this.name +  "]: Cannot start after shutdown");
		}
		if (!this.serverStarted.get()) {
			this.logger.info("JobPool [" + this.name +  "]: starting engine... ");
			this.serverStarted.set(true);
			this.logger.info("JobPool [" + this.name +  "]: engine started.");
		}
	}

	@Override
	public String getName() {
		return this.name;
	}

	@Override
	public boolean isShutdown() {
		return this.shutdown;
	}

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy