
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.JobExecutor;
import com.jpattern.batch.AJob;
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 AJob 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