Thiago Sayão
Thiago Sayão

Reputation: 2347

Spring: endpoint to start a scheduled task

I have a scheduled task that works perfectly, like this:

@Scheduled(cron="*/5 * * * * MON-FRI")
public void doSomething() {
    // something that should execute on weekdays only
}

I want to create a REST endpoint that would start this task out of it's normal schedule.

How would I programatically fire-and-forget this task?

Upvotes: 0

Views: 1675

Answers (2)

Shailendra
Shailendra

Reputation: 9102

This can be done by writing something like below

 @Controller
    MyController {
    
    @Autowired
    MyService myService;
    
     @GetMapping(value = "/fire")
     @ResponseStatus(HttpStatus.OK)
        public String fire() {
            myService.fire();
            return "Done!!";
        }
   }
      
 MyService {
    
@Async
@Scheduled(cron="*/5 * * * * MON-FRI")
public void fire(){
    // your logic here
    
 }
}

Upvotes: 0

Matheus
Matheus

Reputation: 3370

You could do something really simple.

Your schedule:

@Component
@RequiredArgsConstructor
public class MySchedule {

  private final MyClassThatHasTheProcessing process;

  @Scheduled(cron = "*/5 * * * * MON-FRI")
  public void doSomething() {
    // the actual process is made by the method doHeavyProcessing
    process.doHeavyProcessing();
  }

}

Your Controller

@RestController
@RequestMapping(path = "/task")
@RequiredArgsConstructor
public class MyController {

  private final MyClassThatHasTheProcessing process;
  // the executor used to asynchronously execute the task
  private final ExecutorService executor = Executors.newSingleThreadExecutor();

  @PostMapping
  public ResponseEntity<Object> handleRequestOfStartTask() {
    // send the Runnable (implemented using lambda) for the ExecutorService to do the async execution
    executor.execute(() - >{
      process.doHeavyProcessing();
    });

    // the return happens before process.doHeavyProcessing() is completed.
    return ResponseEntity.accepted().build();
  }

}

This will keep your scheduled task working as well as being able do trigger the task on demand by hitting your endpoint.

The HTTP 202 Accepted will be returned and the actual thread released, while the ExecutorService will delegate the process.doHeavyProcessing execution to another thread, which means that it will run in a 'fire and forget' style, because the thread that is serving the request will return even before the other task is finally terminated.

If you don't know what is an ExecutorService, this may help.

Upvotes: 1

Related Questions