es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

“Feign queda atascado dentro del método asincrónico en Spring Boot”

Estoy usando el cliente Feign dentro de un método asíncrono y este método devuelve un Future. Pero mientras estoy ejecutando el servicio, Feign se queda atascado y nunca veo el registro de respuesta del cliente Feign. El bloque de código se queda atascado allí y el servicio deja de estar disponible. Los bloques de código son los siguientes:


@Async public Future<reportresponse> getId(String id) { ReportResponse response = client.getReport(id); log.info("resp for " + response); return new AsyncResult<>(ReportResponse); }

List<><reportresponse>> futuresList = new ArrayList<>(); for (String id : Ids) { futuresList.add(reportService.getId(id)); } for (Future<reportresponse> future : futuresList) { try { ReportResponse reponse = future.get(); } catch (Exception e) { log.error(e.getMessage(), e); } }

@FeignClient(name = "service", url = "${url}", configuration = FeignClientProperties.FeignClientConfiguration.class) public interface Client { @GetMapping(value = "/{id}") ReportResponse getId(@PathVariable String id); }

La dependencia que he usado es:

<dependency>
    <groupid>org.springframework.cloud</groupid>
    <artifactid>spring-cloud-starter-openfeign</artifactid>
</dependency>

¿Alguien puede ayudarme con esto? Gracias.

Tags:  , ,

Answer

  1. Avatar for davy.ai

    Solución:

    El problema con el código proporcionado es que la llamada al cliente Feign bloquea el hilo mientras espera una respuesta. Dado que el método está anotado con @Async, la llamada debe realizarse de forma asíncrona.

    Una forma de solucionarlo es usando un ExecutorService para enviar la llamada al cliente Feign como una tarea separada y luego devolver un Future que se pueda utilizar para recuperar el resultado más tarde. Aquí está una implementación actualizada:

    @Async
    public CompletableFuture<reportresponse> getId(String id) {
        return CompletableFuture.supplyAsync(() -> {
            ReportResponse response = client.getReport(id);
            log.info("resp for " + response);
            return response;
        });
    }
    

    La clase CompletableFuture permite la composición y el cálculo asíncrono, y el método supplyAsync() se utiliza para enviar la llamada al cliente Feign a un executor y devolver un CompletableFuture que se completará con el resultado de la tarea.

    En el controlador, podemos usar CompletableFuture.allOf() para esperar a que se completen todos los futuros y luego recuperar los resultados:

    List<><reportresponse>> futuresList = new ArrayList<>();
    for (String id : Ids) {
        futuresList.add(reportService.getId(id));
    }
    
    CompletableFuture<void> allFutures = CompletableFuture.allOf(futuresList.toArray(new CompletableFuture[0]));
    
    try {
        allFutures.get();
    } catch (Exception e) {
        log.error(e.getMessage(), e);
    }
    
    for (CompletableFuture<reportresponse> future : futuresList) {
        try {
            ReportResponse response = future.get();
            // Hacer algo con la respuesta...
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        }
    }
    

    El método allOf() devuelve un CompletableFuture<void> que se completará cuando se completen todos los futuros de entrada, y podemos esperar su finalización usando get(). Finalmente, podemos iterar a través de los futuros y recuperar los resultados usando get().

    Esto debería solucionar el problema con el código que se queda atrapado mientras espera la respuesta del cliente Feign y hacer que la aplicación sea más receptiva y escalable.

Comments are closed.