Sto implementando long polling as per the Spring blog from some time ago.Come testare il timeout di DeferredResultRisultato
Ecco il mio metodo convertito con la stessa firma di risposta di prima, ma invece di rispondere immediatamente, esso utilizza ora polling lungo:
private Map<String, DeferredResult<ResponseEntity<?>>> requests = new ConcurrentHashMap<>();
@RequestMapping(value = "/{uuid}", method = RequestMethod.GET)
public DeferredResult<ResponseEntity<?>> poll(@PathVariable("uuid") final String uuid) {
// Create & store a new instance
ResponseEntity<?> pendingOnTimeout = ResponseEntity.accepted().build();
DeferredResult<ResponseEntity<?>> deferredResult = new DeferredResult<>(TWENTYFIVE_SECONDS, pendingOnTimeout);
requests.put(uuid, deferredResult);
// Clean up poll requests when done
deferredResult.onCompletion(() -> {
requests.remove(deferredResult);
});
// Set result if already available
Task task = taskHolder.retrieve(uuid);
if (task == null)
deferredResult.setResult(ResponseEntity.status(HttpStatus.GONE).build());
else
// Done (or canceled): Redirect to retrieve file contents
if (task.getFutureFile().isDone())
deferredResult.setResult(ResponseEntity.created(RetrieveController.uri(uuid)).build());
// Return result
return deferredResult;
}
In particolare mi piacerebbe tornare la risposta pendingOnTimeout
quando la richiesta prende troppo lungo (che ho restituito immediatamente prima), per evitare che i proxy interrompano la richiesta.
Ora penso di averlo fatto funzionare così com'è, ma mi piacerebbe scrivere un messaggio inedito che lo confermi. Tuttavia tutti i miei tentativi di usare MockMvc (tramite webAppContextSetup) non mi forniscono un mezzo per affermare che ottengo un'intestazione accepted
. Quando ho per esempio provare quanto segue:
@Test
public void pollPending() throws Exception {
MvcResult result = mockMvc.perform(get("/poll/{uuid}", uuidPending)).andReturn();
mockMvc.perform(asyncDispatch(result))
.andExpect(status().isAccepted());
}
ottengo il seguente stacktrace:
java.lang.IllegalStateException: risultato asincrona per il gestore [org.springframework.web.context.request.async pubblico .DeferredResult> nl.bioprodict.blast.api.PollController.poll (java.lang.String)] non è stato impostato durante il timeToWait specificato = 25000 in org.springframework.util.Assert.state (Assert.java:392) all'indirizzo org.springframework.test.web.servlet.DefaultMvcResult.getAsyncResult (DefaultMvcResult.java:143) all'indirizzo org.springframework.test.web.servlet .DefaultMvcResult.getAsyncResult (DefaultMvcResult.java:120) a org.springframework.test.web.servlet.request.MockMvcRequestBuilders.asyncDispatch (MockMvcRequestBuilders.java:235) a nl.bioprodict.blast.docs.PollControllerDocumentation.pollPending (PollControllerDocumentation .java: 53) ...
I test framework Spring relativi a questo che ho potuto trovare tutto l'uso beffardo che sembra: https://github.com/spring-projects/spring-framework/blob/master/spring-web/src/test/java/org/springframework/web/context/request/async/WebAsyncManagerTimeoutTests.java
Come faccio a testare la corretta gestione del DeferredResult timeoutResult?
Per essere chiari: Sembra funzionare bene in test di integrazione, ma mi piacerebbe anche voler testare questo in 'primavera-restdocs-mockmvc'. – Tim
Mi sono appena imbattuto in questo stesso identico problema. Hai mai trovato una soluzione che permetta di testare i timeout su DeferredResults? –
@John no, non ancora, anche se ho smesso di cercare ora .. Fammi sapere se trovi qualcosa! – Tim