break;
case MAX : currentThread.setPriority(Thread.MAX_PRIORITY);
break;
}
}
JobExecutionResultImpl result = JobExecutionResultImpl.CANCELLED;
Job.JobState resultState = Job.JobState.ERROR;
final AtomicBoolean isAsync = new AtomicBoolean(false);
try {
synchronized ( lock ) {
final JobExecutionContext ctx = new JobExecutionContext() {
private boolean hasInit = false;
@Override
public void initProgress(final int steps,
final long eta) {
if ( !hasInit ) {
handler.persistJobProperties(job.startProgress(steps, eta));
hasInit = true;
}
}
@Override
public void incrementProgressCount(final int steps) {
if ( hasInit ) {
handler.persistJobProperties(job.setProgress(steps));
}
}
@Override
public void updateProgress(final long eta) {
if ( hasInit ) {
handler.persistJobProperties(job.update(eta));
}
}
@Override
public void log(final String message, Object... args) {
handler.persistJobProperties(job.log(message, args));
}
@Override
public boolean isStopped() {
return handler.isStopped();
}
@Override
public void asyncProcessingFinished(final JobExecutionResult result) {
synchronized ( lock ) {
if ( isAsync.compareAndSet(true, false) ) {
services.jobConsumerManager.unregisterListener(job.getId());
Job.JobState state = null;
if ( result.succeeded() ) {
state = Job.JobState.SUCCEEDED;
} else if ( result.failed() ) {
state = Job.JobState.QUEUED;
} else if ( result.cancelled() ) {
if ( handler.isStopped() ) {
state = Job.JobState.STOPPED;
} else {
state = Job.JobState.ERROR;
}
}
finishedJob(job.getId(), state, true);
asyncCounter.decrementAndGet();
} else {
throw new IllegalStateException("Job is not processed async " + job.getId());
}
}
}
@Override
public ResultBuilder result() {
return new ResultBuilder() {
private String message;
private Long retryDelayInMs;
@Override
public JobExecutionResult failed(final long retryDelayInMs) {
this.retryDelayInMs = retryDelayInMs;
return new JobExecutionResultImpl(InternalJobState.FAILED, message, retryDelayInMs);
}
@Override
public ResultBuilder message(final String message) {
this.message = message;
return this;
}
@Override
public JobExecutionResult succeeded() {
return new JobExecutionResultImpl(InternalJobState.SUCCEEDED, message, retryDelayInMs);
}
@Override
public JobExecutionResult failed() {
return new JobExecutionResultImpl(InternalJobState.FAILED, message, retryDelayInMs);
}
@Override
public JobExecutionResult cancelled() {
return new JobExecutionResultImpl(InternalJobState.CANCELLED, message, retryDelayInMs);
}
};
}
};
result = (JobExecutionResultImpl)consumer.process(job, ctx);
if ( result == null ) { // ASYNC processing
services.jobConsumerManager.registerListener(job.getId(), consumer, ctx);
asyncCounter.incrementAndGet();
isAsync.set(true);
} else {
if ( result.succeeded() ) {
resultState = Job.JobState.SUCCEEDED;
} else if ( result.failed() ) {
resultState = Job.JobState.QUEUED;
} else if ( result.cancelled() ) {
if ( handler.isStopped() ) {
resultState = Job.JobState.STOPPED;
} else {
resultState = Job.JobState.ERROR;
}
}
}
}
} catch (final Throwable t) { //NOSONAR
logger.error("Unhandled error occured in job processor " + t.getMessage() + " while processing job " + Utility.toString(job), t);
// we don't reschedule if an exception occurs
result = JobExecutionResultImpl.CANCELLED;
resultState = Job.JobState.ERROR;
} finally {
currentThread.setPriority(oldPriority);
currentThread.setName(oldName);
if ( result != null ) {
if ( result.getRetryDelayInMs() != null ) {
job.setProperty(JobImpl.PROPERTY_DELAY_OVERRIDE, result.getRetryDelayInMs());
}
if ( result.getMessage() != null ) {
job.setProperty(Job.PROPERTY_RESULT_MESSAGE, result.getMessage());
}
finishedJob(job.getId(), resultState, false);
}
}
}