Scatter gather queries are alternating between services instead of going to all defined query handlers

Hey all,

I’m working on implementing a scatter gather query that fetches projection data from two services which are listening for the specific query. Through the logs in each service, I can see that they’re alternating handling the incoming query, instead of each receiving and responding to the incoming query every time I trigger it. Are more configurations required other than defining the query handlers and using the scatterGather function to make it behave how the documentation says that it should behave?

I’m using the standard edition of the axon server, but that shouldn’t impact this functionality, right?

Thanks in advance!

Regards,
Philip

Hi @Philip, can you share some code of your example?

From your description, seems like everything is corrected configured and should be working.

Hey Lucas, sure thing… I’ll pull out what I think are the relevant parts.

Controller:

@RestController
@RequestMapping(value = "/order")
public class HttpController {
  private final QueryGateway queryGateway;
  public HttpController(QueryGateway queryGateway) {
    this.queryGateway = queryGateway;
  }

  @GetMapping("/status")
  public String getStatus(@RequestParam String id) {
    String resp = queryGateway.scatterGather(new StatusQuery(id), ResponseTypes.instanceOf(String.class), 5, TimeUnit.SECONDS)
      .collect(StringBuilder::new, StringBuilder::append, StringBuilder::append)
      .toString();
    return resp;
  }
}

Query defined for both service 1 and 2:

@Data
@AllArgsConstructor
public class StatusQuery {
  private final String id;
}

Order projection in service 1:

@Component
@AllArgsConstructor
public class OrderProjection {
  private OrderHistoryRepository repository;

  // EventHandlers and QueryHandlers unrelated to scatter gather

  @QueryHandler
  public String onStatusScatterGather(StatusQuery query) {
    // Go to the repository and pull the string, then return it
  }
}

Invoice projection in service 2:

@Component
@AllArgsConstructor
public class InvoiceProjection {
  private InvoiceHistoryRepository repository;

  // EventHandlers and QueryHandlers unrelated to scatter gather

  @QueryHandler
  public String onStatusScatterGather(StatusQuery query) {
    // Go to the repository and pull the string, then return it
  }
}

I’m using these dependency versions for Spring and Axon:

axon-spring-boot-starter version 4.0.3
spring-boot-starter-parent version 2.1.3.RELEASE

I tried updating the version to the most recent for both, 4.4.3 and 2.3.4.RELEASE and the behavior stays how I described, so I must be doing something wrong. Any pointers would be great, Lucas.

@lfgcampos is that example good enough? Do you need more info?

Hi @Philip, thanks for the example. They were good enough.

I’ve set up a test project for a scatterGather, similar to your example and it works fine.

One thing I noticed though, is the way you are appending all the responses into a single String: .collect(StringBuilder::new, StringBuilder::append, StringBuilder::append).
Maybe this is why you only see one response?

Since you already said you added logs to each service, you can also add a peek to the responses returned by the scatterGather to make sure what you are getting back.

Another thing to ask is about error logs, do you see anything happening on you application log or axon-server logs?

KR.
Lucas