chris01
chris01

Reputation: 12321

Spring Boot: Scalable tasks like Threads - how to do?

I am starting with Spring Boot and want to execute tasks.

Lets say my application knows different clients. For any client I like to do a periodic action (e.g. check a mail-account every minute). The number of clients may vary during the execution of the application (e.g. out of a DB table that grows or shrinks in time).

In a "normal" program I would start a thread for any client that does the mail-handling inside a endless loop with a delay. During execution the number of threads would vary.

How can I do such tasks with Spring Boot? I would expect some tools beside threads out of the framework.

I know Components with @Scheduled but that is static and not dynamically to control (as far I know).

Upvotes: 0

Views: 210

Answers (2)

Derrops
Derrops

Reputation: 8117

There is a few ways to go about this, I guess to it depends on whether you can do all the work within the Schedule for clients or not

If you can you can simply loop through all the clients checking their mail. If you cant in your Scheduled action you don't do the work, but instead calculate the work which is needing to be done, and put that work in a queue, there could be 1 message per client, or you might batch some clients up, and then there would be workers which read work from this queue.

If your queue starts to bank up, and work is coming in quicker than you can do it, then adjust your schedule to be less frequent, or add workers.

Upvotes: 0

Santiago Medina
Santiago Medina

Reputation: 579

You can use the spring TaskScheduler. Let's say you have a client handler component responsible for scheduling and stopping jobs for each client.

You can inject the TaskScheduler:

@Autowired
private TaskScheduler taskScheduler;

Then start a job for a specific client when your application requires:

CronTrigger cronTrigger = new CronTrigger(yourCronExpression);
ScheduledFuture<?> jobHandler = this.taskScheduler.schedule(new Runnable() {
    @Override
    public void run() {
        // You can put your code here or get statically an instance of a component to invoke
    }
}, cronTrigger);

Finally, you can put the returned jobHandler in a map by client ID, and use it if you have to stop a scheduled task later:

this.yourHandlersMap.get(clientId).cancel(false);

Upvotes: 1

Related Questions