问题
Currently, I expose a rest endpoint in my application that kick of spring batch jobs.
However, the requests are not scheduled asynchronously. Response is provided after job completes with batch status in the MyResponse
object.
@RestController
@RequestMapping("/test")
public class TestController {
private MyProcessor processor;
private RequestDataRepo repo;
public TestController(final MyProcessor processor, final RequestDataRepo repo) {
this.feedProcessor = feedProcessor;
this.repo = repo;
}
@PostMapping(value = "/kickOfJob", consumes = MediaType.APPLICATION_JSON_VALUE)
public HttpEntity<MyReponse> trigger(@Valid @RequestBody MyRequest request) {
final String trackingId = UUID.randomUUID().toString();
final RequestEntity entity = RequestEntity.builder()
.trackingId(trackingId)
.name(request.getName())
.build();
this.repo.save(entity);
MyReponse response = processor.process(request, trackingId);
return new ResponseEntity<>(response, CREATED);
}
}
I would like to process the requests asynchronously that is giving the response back straight away to caller with the trackingId
in the MyResponse
object and also reply with the initial status. The idea is client will call another endpoint later to check status.
I need a hand with implementing Async processing. I created the below service which contains a blocking queue to hold the job submissions and threads. How can I decouple processing from RestController? I am looking to submit the task to queue after saving the request to db and send initial response back.
Unfortunately, I am stuck here on how to submit task and have it taken out of the queue and processed in the background. When it is complete, it should update the db with new status. On bootup, it should be able to read from db and resubmit the tasks to the queue for processing. Let's say container died during processing task.
P.S I prefer a custom thread pool service for my application.
Appreciate if you can get me started :)
@Service
@Slf4j
public class BatchJobPublisherService {
private final BlockingQueue<MyRequest> jobQueue;
private final ExecutorService executorService;
public BatchJobPublisherService() {
this.jobQueue = new LinkedBlockingDeque<>();
this.executorService = Executors.newFixedThreadPool(10);
}
/**
**/
}
public class MyResponse {
private final String name;
private String trackingId;
private JobStatus jobStatus;
}
public class Processor {
private JobLauncher jobLauncher;
private JobExplorer jobExplorer;
private JobLocator jobLocator;
//Constructor
public Processor process(MyRequest request, String trackingId) {
//get job, build params here
jobLauncher.run(job, parameters);
return createAResponse(request, trackingId, jobExecution);
}
}
来源:https://stackoverflow.com/questions/62779493/java-spring-processing-spring-batch-job-requests-asynchronously