Shedlock with Spring Cloud Function @PollableBean

I have recently switched the implementation of almost all our services to spring cloud function, and naturally that mean as well that all scheduled jobs have been converted to suppliers, for example from this

@Scheduled(cron = "${retry.job.cron.time}")
@SchedulerLock(name = "retryProcess_scheduledTask", lockAtMostFor = "${retry.job.lock.atMost}", lockAtLeastFor = "${retry.job.lock.atLeast}")
public void retryUnprocessedItems() { ...}

to this

@PollableBean
public Supplier<List<Message<ProductValidatedEvent>>> retryUnprocessedItems() { ... }

As you can see the only obstacle here is implemented some sort of a distributed lock mechanism to prevent those PollableBean annotated Suppliers from starting on all service instances.

I have thought about reverting back the scheduled jobs to where they were and use StreamBridge to resolve this, but this sounded like a hack more than a solution.

Another Idea was to convert the supplier into a Function interface type, and call it through a normal @Scheduled annotated method, but this does not seems to set well with Spring cloud function as well.

Any Ideas?


Solution 1:

this is really interesting. I see two ways of solving this.

  1. The most straigntforward is to use AOP on another method
@PolllableBean
public Supplier<Void> retryUnprocessedItems(){ 
    return otherBean::doIt;
}

class OtherBean {
  @SchedulerLock(...)
  public void doIt() {
    ....
  }
}

please note that the method is implemented on different class to allow AOP to work. Also I had to change the return type to Void as we would not know what to return in case the lock is locked.

  1. The other option is to use locking without framework