Class HttpRemoteCommandDispatcher

java.lang.Object
io.axoniq.framework.springcloud.command.HttpRemoteCommandDispatcher
All Implemented Interfaces:
RemoteCommandDispatcher

public class HttpRemoteCommandDispatcher extends Object implements RemoteCommandDispatcher
The RemoteCommandDispatcher that sends commands to other members over HTTP, and reads back their outcome.

RestClient is synchronous, so each dispatch runs on the supplied Executor rather than on the caller's thread — the connector's dispatch must not block. A virtual-thread-per-task executor suits this well: the work is a blocking HTTP round trip and nothing else, so the number of commands in flight is bounded by the far side's capacity rather than by a thread pool of this member's choosing.

A failure to reach the member, or to read its reply, surfaces as a MemberUnreachableException — distinct from a failure the member itself reported, which arrives inside the reply and surfaces as the exception that reply describes. The connector uses that distinction to decide whether to hold the member responsible, so only the former may use this exception.

Every dispatch is given a deadline. A member that stops answering without saying so — one that was killed, or partitioned away — leaves a socket that reports nothing, which would otherwise hold the dispatch unresolved for as long as the operating system allows. Reaching the deadline is reported as a failure to reach the member, so the connector takes it out of the ring like any other member it could not reach.

Note that the deadline bounds when the dispatch completes, not the HTTP exchange itself: the thread running the round trip stays blocked in the RestClient until the socket gives up. Connect and read timeouts belong on the client's own request factory, and the Spring Boot autoconfiguration sets them on the RestClient it contributes.

Since:
5.4.0
Author:
Allard Buijze
  • Field Details

    • DEFAULT_REPLY_TIMEOUT

      public static final Duration DEFAULT_REPLY_TIMEOUT
      How long a member is given to answer a command when no other deadline is configured.
  • Constructor Details

    • HttpRemoteCommandDispatcher

      public HttpRemoteCommandDispatcher(org.springframework.web.client.RestClient restClient, String commandEndpoint, Executor executor, @Nullable MessageConverter converter)
      Constructs an HttpRemoteCommandDispatcher sending commands with the given restClient.
      Parameters:
      restClient - the client used to send commands to other members
      commandEndpoint - the path, relative to a member's base URI, other members receive commands under. Must match the path SpringCloudCommandController is mapped to across the cluster.
      executor - the executor the blocking HTTP round trips run on
      converter - the converter attached to received results for inline payload conversion, and used to convert application-specific exception details, or null when none is available
    • HttpRemoteCommandDispatcher

      public HttpRemoteCommandDispatcher(org.springframework.web.client.RestClient restClient, String commandEndpoint, Executor executor, @Nullable MessageConverter converter, Duration replyTimeout)
      Constructs an HttpRemoteCommandDispatcher giving each command replyTimeout to be answered in.
      Parameters:
      restClient - the client used to send commands to other members
      commandEndpoint - the path, relative to a member's base URI, other members receive commands under. Must match the path SpringCloudCommandController is mapped to across the cluster.
      executor - the executor the blocking HTTP round trips run on
      converter - the converter attached to received results for inline payload conversion, and used to convert application-specific exception details, or null when none is available
      replyTimeout - how long a member is given to answer a command before it is treated as unreachable
  • Method Details

    • dispatch

      public CompletableFuture<@Nullable CommandResultMessage> dispatch(Member member, CommandMessage command)
      Description copied from interface: RemoteCommandDispatcher
      Sends the given command to the given member and completes with the outcome of handling it there.
      Specified by:
      dispatch in interface RemoteCommandDispatcher
      Parameters:
      member - the member to send the command to. Never local
      command - the command to send
      Returns:
      a future completing with the result of handling the command on the given member, with null when its handler returned none; completing exceptionally with a CommandDispatchException when the member could not be reached, and with the handler's own failure when it ran and failed