Estou usando @MessagingGateway
para fazer a ponte entre spring-mvc
@Controller
e spring-integration
. A @MessagingGateway
declaração fica assim:
package a.b.c;
import org.springframework.integration.annotation.*;
import org.springframework.stereotype.Component;
@MessagingGateway(name="inboundGateway" defaultRequestTimeout="2000"
defaultReplyTimeout="2000")
@Component
public interace InboundGateway {
@Gateway(requestChannel = "getSomething")
Message<SomeValue> getSomething(@Headers Map<String, Object> headers);
}
que é referenciado por um controlador
@Controller
@RequestMapping("/some/base/path")
public class SomeController {
private final InboundGateway inboundGateway;
public SomeController(InboundGateway inboundGateway) {
this.inboundGateway = inboundGateway;
}
@GetMapping(value = "things", produces = { "application/json" })
public ResponseEntity<SomeValue> getSomething(RequestContext<String> requestContext) {
Message<SomeValue> response = inboundGateway.getSomething(requestContext);
....
}
Eu estava pensando que as definições de defaultRequestTimeout
e defaultReplyTimeout
gerariam um tempo limite inboundGateway
se a resposta não fosse retornada dentro do tempo especificado.
Porém, estou vendo que o tempo utilizado no método getSomething()
pode ultrapassar o tempo especificado, neste exemplo, 2 segundos. Parece que os 2 segundos são usados como tempo limite para as chamadas para sistemas downstream, mas não como tempo limite para o retorno de getSomething()
.
Estou entendendo isso corretamente? Existe alguma maneira simples e declarativa de gerenciar o tempo limite no inboundGateway
nível? Qualquer indicação será apreciada.
O comportamento que você explica é típico de fluxos em que você
inboundGateway
é um arquivoDirectChannel
. Dessa forma, o processo da mensagem é executado diretamente no thread que produz essa mensagem. Portanto, ele não pode alcançar oreplyTimeout
resultado for, pois esse thread está bloqueado aguardando o tratamento da mensagem.Veja mais informações nos documentos para diferentes canais: https://docs.spring.io/spring-integration/reference/channel/implementations.html
Consulte também a documentação sobre esses tempos limite no Gateway: https://docs.spring.io/spring-integration/reference/gateway.html
Como uma solução simples para sua expectativa, você pode considerar usar um
QueueChnanel
for thatinboundGateway
ou umExecutorChannel
. Desta forma, o processamento será transferido para um thread diferente e o gateway poderá facilmente passar para o bloco de espera de resposta. E é aí que issoreplyTimeout
terá efeito.Também é explicado naquele atributo de anotação JavaDocs: