Producer

πŸ“Œ Purpose

The CampaignExecutionProducer component is responsible for automatically creating CampaignExecutionarrow-up-right instances based on a preconfigured schedule. It periodically checks campaigns with status SCHEDULED and triggers execution if the time has come.


πŸ”§ Class: CampaignExecutionProducer

@Component
public class CampaignExecutionProducer {

    @Autowired
    private CampaignRepository campaignRepository;
    @Autowired
    private CampaignExecutionService executionService;
    @Autowired
    private TransactionTemplateBuilder ttb;

    @SchedulerLock(name = "CampaignExecutionProducer_produce", lockAtMostFor = "PT5M", lockAtLeastFor = "PT30S")
    @Scheduled(initialDelay = 120_000, fixedDelayString = "${campaign.execution.producer.fixedDelay}")
    public void produce() {
        final LocalDateTime now = LocalDateTime.now(ZoneId.systemDefault());
        campaignRepository.findAutomaticScheduledCampaigns()
            .forEach(id -> {
                ttb.requiresNew().executeWithoutResult(s -> {
                    Campaign campaign = campaignRepository.getSync(id);
                    if (campaign.isActive()
                        && campaign.getAutomaticCampaignStatus() == AutomaticCampaignStatus.SCHEDULED
                        && isWaitNewExecution(campaign, now)) {
                        executionService.createExecution(campaign);
                        campaignRepository.saveAndFlush(campaign);
                    }
                });
            });
    }

    // Helper methods below...
}

⏰ Execution Frequency

The @Scheduled annotation launches the produce() method at intervals defined in configuration:

The @SchedulerLock annotation (via Shedlock) ensures the method runs in only one service instance in a clustered deployment.


🧠 Conditions for Creating a New CampaignExecution

The produce() method creates a new execution only if all of the following are true:

  • The campaign is active

  • Its status is SCHEDULED

  • The current time now is equal to or after dateTimeExecution

  • Depending on the restartable flag, one of the following applies:

    • All previous executions are DISABLED

    • The next scheduled interval has arrived (based on restart configuration)


πŸ” Support for restartable Campaigns

βœ… If restartable = false

Only one execution is allowed β€” further executions require all previous ones to be disabled.


πŸ” If restartable = true

This enables cyclic execution (e.g., once every hour/day) based on restartableUnit and restartableUnitType.


🧩 Helper Method

This method consolidates all logic for determining whether a new execution should be created.


πŸ“ Example Behavior

Campaign A:

  • executionType = AUTOMATIC

  • dateTimeExecution = 2025-05-01T09:00

  • restartable = true

  • restartableUnitType = HOURS, restartableUnit = 6

Producer output:

  • May 1, 09:00 β†’ first execution

  • May 1, 15:00 β†’ second execution

  • May 1, 21:00 β†’ third execution

  • ...


πŸ“Œ Summary

  • CampaignExecutionProducer is an automatic campaign scheduler

  • Controlled via @Scheduled and @SchedulerLock

  • Checks campaign status, activation, execution time, and recurrence settings

  • Operates in a new isolated transaction, preventing interference with outer processes

Last updated

Was this helpful?