Answer the question
In order to leave comments, you need to log in
How to make friends between web flux long polling request and scheduled method?
It is not possible to make the long polling request and the scheduled method work in parallel. I have an external data source. Once every 3 seconds, the scheduled method accesses this data source and fetches some data, storing it in my database, adding a timestamp (timestamp attribute) when the data was updated. To make life easier for the web application, I decided to add a long polling method that would wait for the timestamp field to change and, in case of a change, would return a dto with updated data. Or the old dto if there were no changes in 12 seconds.
Scheduled method is clear, simple method with @Schedule(fixedDelay) annotation
Long polling methods looks something like this
@GetMapping("/hook")
public Mono<DataDto> publisher(@PathVariable String account) {
var currentSession = service.load(account);
if(currentSession.isEmpty()) {
return Mono.empty();
}
try {
Thread.sleep(3000);
for(int i = 0; i < 4; i++) {
var tempSession = service.load(account);
if (currentSession.get().getTimestamp() < tempSession.get().getTimestamp()) {
Mono.just(tempSession.get().dto());
}
Thread.sleep(3000);
}
Mono.just(currentSession.get().dto());
} catch (Exception e) {
log.error("error waiting new data", e);
}
throw new RuntimeException("dvferfge");
}
Answer the question
In order to leave comments, you need to log in
It seems to have worked. Rewrote everything reactively. The handler stopped blocking the scheduler. Maybe with two Mono.defer it's overkill, but I don't know how to do it differently yet. It is still unclear to me whether this call is in place with take(4) yet.
@GetMapping("/hooks/{account}/new_game")
public Mono<TableauDto> publisher(@PathVariable String account) {
log.debug("hooks/new_game {}", account);
return Mono.defer(() -> {
log.debug("get current startBlock {}", account);
final var currentStartBlock = service
.load(account)
.map(session -> session.getStartBlock())
.orElse(0l);
var res = Mono.defer(() -> service.getTableau(account, currentStartBlock))
.repeatWhenEmpty(c -> c.delayElements(Duration.ofMillis(3000)).take(4));
log.debug("return res {}", res.single());
return res;
});
}
Didn't find what you were looking for?
Ask your questionAsk a Question
731 491 924 answers to any question