-1

I have splitted a list in 5 parts, and I want to execute in parallel using restTemplate, I have the following method:

@Async
private CompletableFuture<List<Cidade>> MontarCidadesPorEstado(List<Cidade> listaCidades, List<UF> estado) {

    estado.forEach(es -> {
            Map<String, String> param = new HashMap<String, String>();
            param.put("UF", es.getSigla());

            Cidade[] cidades = restTemplate.getForObject(url, Cidade[].class, param);

            listaCidades.addAll(Arrays.asList(cidades));
     });

    return CompletableFuture.completedFuture(listaCidades);
}

So created a List of CompletableFuture to execute all of them in parallel, but when an add each CompletableFuture into a list it's already execute it without make it parallel, ex:

     List<List<UF>> subSets = Lists.partition(estados, 5);
     List<CompletableFuture<List<Cidade>>> lstCompletableFuture = new ArrayList();

     subSets.forEach(estado -> {
         lstCompletableFuture.add(MontarCidadesPorEstado(listaCidades, estado));
     });

     CompletableFuture.allOf(lstCompletableFuture.toArray(new CompletableFuture[lstCompletableFuture.size()]));

What I'm doing wrong, I thought it's supposed to execute the method MontarCidadesPorEstado when I call CompletableFuture.allOf.

M--
  • 25,431
  • 8
  • 61
  • 93
Fernando josé
  • 249
  • 4
  • 10

1 Answers1

0

I assume that MontarCidadesPorEstado is a local method call.

Therefore the call is local it doesn't go through a proxy and is not asynchronous.

You have define the MontarCidadesPorEstado method in another bean and then call this bean.

Simon Martinelli
  • 34,053
  • 5
  • 48
  • 82
  • What does defining it in another bean achieve from a concurrency standpoint? – Savior May 29 '20 at 13:02
  • @Savior : took me a while to see, but the question is tagged "spring" and there is `@Async` on the method. Therefore the OP thinks his method should be async (executed on another thread), because he used the annotation, (and not because he uses completable futures). In this context, Simon's answer makes sense : the `@Async` is not triggered because `@Async` annotations trigger only through AOP on Spring, which needs non-local calls (in Spring, most aspects are placed at object boundaries, not at local method boundaries). – GPI May 29 '20 at 13:07
  • @GPI I see, thank you. So OP intends for MontarCidadesPorEstado to happen async, got it. – Savior May 29 '20 at 13:18
  • So as not to leave too misleading vocabulary, what I mean by "most aspects are placed at object boundaries" really is more : annotation driven behavior is most often implemented by altering the user bean (decoration, AOP, proxying, or other mean), which amounts to "wrapping" it (this wrapper then becomes the Spring-managed bean). So the behavior is triggered when you call the wrapper, and not the wrapped instance. That's why local method calls inside a bean, which happen inside the wrapped instance, do not trigger many annotation driven behaviors, among which `@Transactionnal` or `@Async`. – GPI May 29 '20 at 13:28
  • i put MontarCidadesPorEstado in another service and it works, thanks... – Fernando josé May 29 '20 at 14:07