I would like to be able to report a certain method's progress in Spring Boot. I used a seperate class which I store the current status in and return as the current view: It looks like this:
public class SearchTableReloadState {
//STATIC STORAGE
public static long TABLE_ROW_COUNT = 0;
public static long CURRENT_OFFSET = 0;
public static long CURRENT_LIMIT = 0;
public static long DEFAULT_LIMIT = 20000;
public static void reset() {
TABLE_ROW_COUNT = 0;
CURRENT_OFFSET = 0;
CURRENT_LIMIT = DEFAULT_LIMIT;
}
public static void setDefaultLimit(long defaultLimit) {
DEFAULT_LIMIT = defaultLimit;
}
// VIEWMODEL
public long tableRowCount = 0;
public long currentOffset = 0;
public long currentLimit = 0;
public static SearchTableReloadState getState() {
SearchTableReloadState reloadState = new SearchTableReloadState();
reloadState.tableRowCount = TABLE_ROW_COUNT;
reloadState.currentOffset = CURRENT_OFFSET;
reloadState.currentLimit = CURRENT_LIMIT;
return reloadState;
}
}
And the methods:
@RequestMapping(value = {"/manage/searchtable/reload/state"}, method = RequestMethod.GET)
public @ResponseBody SearchTableReloadState searchTableReloadState() {
return SearchTableReloadState.getState();
}
@ResponseStatus(HttpStatus.OK)
@RequestMapping(value = {"/manage/searchtable/reload"}, method = RequestMethod.GET)
public void searchTableReload() throws ResourceAlreadyExistsException, ParameterMissingIdException {
SearchTableReloadState.reset();
SearchTableReloadState.TABLE_ROW_COUNT = productDataReferenceDao.countJobReferences();
productDataReferenceDao.truncateSearchTable();
while (SearchTableReloadState.CURRENT_OFFSET < SearchTableReloadState.TABLE_ROW_COUNT) {
... long running task
....
SearchTableReloadState.CURRENT_OFFSET += SearchTableReloadState.CURRENT_LIMIT;
}
}
The method with the /state would report the current state, so I could call these with Ajax on a site. Problem is, If I start the long running one, the state report request won't complete until the long running did not complete. I thought Spring uses separate threads for each request. Do I need to implement threading in Spring?
If I use the @Async
annotation for the long running process, it works like I expected, but I still don't understand, why could two separate HTTP requests for a different method block each other!
If I use the @Async
annotation on the method that is supposed to take a long time, the HTTP Request calling it will get a response immediately and it will run in the background and I can call the state method as I expected. Even though it is working, I still don't know why it won't work without the asynchronous execution.
If you want to use the @Async
annotation, you have to put the @EnableAsync
annotation on the class you used the @SpringBootApplication
and/or @EnableAutoConfiguration
.
I hope someone can provide a better answer later.