简体   繁体   中英

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?

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

Based on Lukas answer above, I have been able to update my code so that it uses Spring AOP, I have created a ScheduledTask Component with only one method that contains the Supplier logic, marked with @SchedulerLock annotation, and returning the value to be emitted by the supplier later on to the Kafka topic

@Autowired
ScheduledTask task;

@PollableBean
public Supplier<String> getScheduledJob() {
    return task::fire;
}

@Slf4j
@Component
class ScheduledTask {
    @SchedulerLock(name = "myJobLock", lockAtMostFor = "10s", lockAtLeastFor = "1s")
    public String fire() {
        log.info("Task was fired");
        return (String.valueOf(System.currentTimeMillis()));
    }
}

You can find a running sample here https://github.com/Mahm0ud/ShedlockWithSpringCloudFunction

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM