Skip to content

Commit

Permalink
Merge pull request #3 from sterlp/apply-retry-delay
Browse files Browse the repository at this point in the history
apply a delay on an error
  • Loading branch information
sterlp committed Jun 1, 2024
2 parents d5eed07 + 35758f6 commit 2b9b785
Show file tree
Hide file tree
Showing 7 changed files with 51 additions and 7 deletions.
2 changes: 1 addition & 1 deletion core/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
<parent>
<groupId>org.sterl.pmw</groupId>
<artifactId>pmw-root</artifactId>
<version>1.1.2-SNAPSHOT</version>
<version>1.2.1-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

Expand Down
4 changes: 2 additions & 2 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

<groupId>org.sterl.pmw</groupId>
<artifactId>pmw-root</artifactId>
<version>1.1.2-SNAPSHOT</version>
<version>1.2.1-SNAPSHOT</version>
<packaging>pom</packaging>

<inceptionYear>2022</inceptionYear>
Expand Down Expand Up @@ -49,7 +49,7 @@
</distributionManagement>

<properties>
<pmw.version>1.1.2-SNAPSHOT</pmw.version>
<pmw.version>1.2.0</pmw.version>
<java.version>17</java.version>
<maven.compiler.source>${java.version}</maven.compiler.source>
<maven.compiler.target>${java.version}</maven.compiler.target>
Expand Down
2 changes: 1 addition & 1 deletion spring/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
<parent>
<groupId>org.sterl.pmw</groupId>
<artifactId>pmw-root</artifactId>
<version>1.1.2-SNAPSHOT</version>
<version>1.2.1-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,10 @@ public class QuartzWorkflowJob implements Job {
private final Workflow<?> workflow;
@NonNull
private final TransactionTemplate trx;
/**
* In case of an error this strategy is applied if no delay is already set
*/
private final RetryDelayStrategy defaultDelayStrategy;
@NonNull
private final WorkflowStateParserComponent workflowStateParser;

Expand Down Expand Up @@ -65,6 +69,12 @@ public void execute(JobExecutionContext context) throws JobExecutionException {
else throw new JobExecutionException(cause, true);

} catch (WorkflowException.WorkflowFailedDoRetryException retryE) {
// apply a default delay, if non was already set
if (!runningWorkflowState.internalState().hasDelay()) {
final var newDelay = defaultDelayStrategy.retryAt(
runningWorkflowState.internalState().getStepRetryCount(), retryE);
runningWorkflowState.internalState().delayNextStepBy(newDelay);
}

workflowService.rescheduleTrigger(context.getTrigger(),
runningWorkflowState.internalState(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

import com.fasterxml.jackson.databind.ObjectMapper;

import jakarta.annotation.Nullable;
import lombok.NonNull;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
Expand All @@ -32,7 +33,11 @@ public class QuartzWorkflowJobFactory implements JobFactory {
private final ObjectMapper mapper;
@NonNull
private final TransactionTemplate trx;

/**
* In case of an error this strategy is applied if no delay is already set
*/
private final RetryDelayStrategy defaultDelayStrategy;
@Nullable
private final JobFactory delegate;

@Override
Expand All @@ -47,6 +52,8 @@ public Job newJob(TriggerFiredBundle bundle, Scheduler scheduler) throws Schedul
return delegate.newJob(bundle, scheduler);
}

return new QuartzWorkflowJob(strategy, workflowService, w.get(), trx, new WorkflowStateParserComponent(mapper));
return new QuartzWorkflowJob(strategy, workflowService, w.get(), trx,
defaultDelayStrategy,
new WorkflowStateParserComponent(mapper));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package org.sterl.pmw.quartz.job;

import java.time.Duration;

import org.sterl.pmw.exception.WorkflowException;

@FunctionalInterface
public interface RetryDelayStrategy {
RetryDelayStrategy NO_DELAY = (c, e) -> Duration.ZERO;
RetryDelayStrategy LINEAR_DELAY = (c, e) -> Duration.ofMinutes(c + 1);
RetryDelayStrategy EXPONENTIAL_DELAY = (c, e) -> Duration.ofMinutes((long)Math.pow(c + 1, 2));

/**
* By default a linear retry strategy, adding one minute for each failed try.
*/
Duration retryAt(int stepRetryCount, WorkflowException.WorkflowFailedDoRetryException error);
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.quartz.SchedulerFactoryBeanCustomizer;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
Expand All @@ -15,6 +16,7 @@
import org.sterl.pmw.component.WorkflowRepository;
import org.sterl.pmw.quartz.boundary.QuartzWorkflowService;
import org.sterl.pmw.quartz.job.QuartzWorkflowJobFactory;
import org.sterl.pmw.quartz.job.RetryDelayStrategy;

import com.fasterxml.jackson.databind.ObjectMapper;

Expand All @@ -32,12 +34,18 @@ public class WorkflowConfig {
WorkflowRepository workflowRepository() {
return new WorkflowRepository();
}
@Bean
@ConditionalOnMissingBean
RetryDelayStrategy delayStrategy() {
return RetryDelayStrategy.NO_DELAY;
}

@Bean
QuartzWorkflowService quartzWorkflowService(
ApplicationContext applicationContext,
Scheduler scheduler,
ObjectMapper mapper,
RetryDelayStrategy delayStrategy,
TransactionTemplate trx) throws SchedulerException {

final QuartzWorkflowService quartzWorkflowService = new QuartzWorkflowService(scheduler, workflowRepository(), mapper);
Expand All @@ -50,7 +58,9 @@ QuartzWorkflowService quartzWorkflowService(
}

scheduler.setJobFactory(new QuartzWorkflowJobFactory(
new SimpleWorkflowStepExecutor(), quartzWorkflowService, mapper, trx, jobFactory));
new SimpleWorkflowStepExecutor(), quartzWorkflowService,
mapper, trx,
delayStrategy, jobFactory));

return quartzWorkflowService;
}
Expand Down

0 comments on commit 2b9b785

Please sign in to comment.