How to dynamically turn on/off a scheduled method in a springboot application
Asked Answered
D

2

11

I am building a Springboot application and I want to turn on a scheduled method from the front-end. (as in I want the scheduler to run only after the method is called from the front-end)

This scheduled method will then call a web-service with the given parameter and keep on running until a specific response ("Success") is received.

Once the specific response is received, I want the scheduled method to stop running until it is called again from the front end.

I am not sure how to start and stop the execution of the scheduled method.

I have this currently:

@Component
public class ScheduledTasks {

    private static final Logger LOG = LoggerFactory.getLogger(ScheduledTasks.class);

    private static final SimpleDateFormat dateFormat = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss");

    @Scheduled(fixedRate = 5000)
    public void waitForSuccess(String componentName) {
        LOG.info("Running at: " + dateFormat.format(new Date()));
        String response = MyWebService.checkStatus(componentName);
        if ("success".equalsIgnoreCase(response)) {
            LOG.info("success");
            //Stop scheduling this method
        } else {
            LOG.info("keep waiting");
        }
    }
}

Here is my controller through which the scheduled method is to be turned on:

@Controller
public class MainController {

    @GetMapping(/start/{componentName})
    public @ResponseBody String startExecution(@PathVariable String componentName) {
        //do some other stuff
        //start scheduling the scheduled method with the parameter 'componentName'
        System.out.println("Waiting for response");
    }

}

Is my approach correct? How can I achieve this functionality using springboot and schedulers?

Devereux answered 9/6, 2017 at 18:32 Comment(1)
Why not specify a static AtomicBoolean that specifies if the code should be executed or not by using a while loop on it?Verger
I
13

Here is the full example of start/stop API for a scheduled method in Spring Boot. You can use such APIs:
http:localhost:8080/start - for starting scheduled method with fixed rate 5000 ms
http:localhost:8080/stop - for stopping scheduled method

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.scheduling.TaskScheduler;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import java.time.Instant;
import java.util.concurrent.ScheduledFuture;

@Configuration
@ComponentScan
@EnableAutoConfiguration    
public class TaskSchedulingApplication {

    public static void main(String[] args) {
        SpringApplication.run(TaskSchedulingApplication.class, args);
    }

    @Bean
    TaskScheduler threadPoolTaskScheduler() {
        return new ThreadPoolTaskScheduler();
    }
}

@Controller
class ScheduleController {

    public static final long FIXED_RATE = 5000;

    @Autowired
    TaskScheduler taskScheduler;

    ScheduledFuture<?> scheduledFuture;

    @RequestMapping("start")
    ResponseEntity<Void> start() {
        scheduledFuture = taskScheduler.scheduleAtFixedRate(printHour(), FIXED_RATE);

        return new ResponseEntity<Void>(HttpStatus.OK);
    }

    @RequestMapping("stop")
    ResponseEntity<Void> stop() {
        scheduledFuture.cancel(false);
        return new ResponseEntity<Void>(HttpStatus.OK);
    }

    private Runnable printHour() {
        return () -> System.out.println("Hello " + Instant.now().toEpochMilli());
    }

}
Igenia answered 27/9, 2017 at 8:59 Comment(1)
Also, check this link for related solution which uses map to keep track of schedulers, and cancelling only required ones.Amaya
A
0
  1. Start/stop API for a scheduled method in Spring Boot.

    @Component
    public class ScheduledTasks  {
    
        private Logger logger = Logger.getLogger(ScheduledTasks.class);
    
        @Value("${jobs.schedule.istime}")
        private boolean imagesPurgeJobEnable;
    
        @Override
        @Transactional(readOnly=true)
        @Scheduled(cron = "${jobs.schedule.time}")
        public void execute() {
    
             //Do something
            //can use DAO or other autowired beans here
            if(imagesPurgeJobEnable){
    
               // Do your conditional job here...
    
            }
       }
    }
    
Aldrin answered 9/6, 2017 at 18:53 Comment(2)
Could you at least write one or two sentences to describe your solution?Relegate
You will need to use at least to values for this solution work, once you are using the same jobs.schedule.istime for two differente kind of variables.Sarmatia

© 2022 - 2024 — McMap. All rights reserved.