Class SpringCloudQueryBusConnector
- All Implemented Interfaces:
QueryBusConnector,DescribableComponent
QueryBusConnector distributing queries over the members a Spring Cloud discovery implementation reports.
Where a command is routed to one member by its routing key, a query asks nothing of where it is handled: any member advertising the query's name may answer it. Successive queries of a name therefore rotate over the members advertising it, spreading the load rather than sending every one to the same member.
A query is answered with a stream of responses rather than a single result, so the responses arrive as they are
produced. A member answering faster than this application consumes fails the query rather than buffering without
limit; see HttpRemoteQueryDispatcher.
A subscription query reaches every member advertising its name, not just the one a plain query would route to: an
update is emitted on whichever member's state changed, and only reaches subscriptions that member holds a
registration for. One of them answers the initial result as well, so a subscriber gets one initial result and the
updates of the whole cluster. The initial result is asked for only once every one of those members has registered
the subscription, so that an update emitted in the meantime reaches the subscriber rather than nobody. A member that
starts advertising the query while a subscription is active fails that subscription rather than joining it late;
see SubscriptionQueryMembersChangedException.
- Since:
- 5.4.0
- Author:
- Allard Buijze
-
Nested Class Summary
Nested classes/interfaces inherited from interface io.axoniq.framework.messaging.queryhandling.distributed.QueryBusConnector
QueryBusConnector.Handler, QueryBusConnector.UpdateCallback -
Constructor Summary
ConstructorsConstructorDescriptionSpringCloudQueryBusConnector(SpringCloudMemberDiscovery discovery, IncomingQueryInvoker invoker, RemoteQueryDispatcher dispatcher, @Nullable MessageConverter converter) Constructs aSpringCloudQueryBusConnectorrouting with the givendiscovery. -
Method Summary
Modifier and TypeMethodDescriptionvoiddescribeTo(ComponentDescriptor descriptor) Describe the properties ofthis DescribableComponentwith the givendescriptor.Stops advertising the queries this member handles, and tells the subscribers it is still answering that it is leaving.voidonIncomingQuery(QueryBusConnector.Handler handler) Registers a handler to process incoming query messages.query(QueryMessage query, @Nullable ProcessingContext context) Sends the givenqueryto the remote QueryBus.Stops dispatching new queries, and waits for the responses to the ones already dispatched.voidstart()Prepares this connector for dispatching queries, after a previousshutdownDispatching()if any, and for answering subscriptions again, after a previousdisconnect()if any.subscribe(QualifiedName queryName) Subscribes this connector to queries matching the givenname.subscriptionQuery(QueryMessage query, @Nullable ProcessingContext context, int updateBufferSize) Sends the givenqueryto the remote QueryBus.booleanunsubscribe(QualifiedName queryName) Unsubscribes this connector from queries with the givenname.
-
Constructor Details
-
Method Details
-
query
public MessageStream<QueryResponseMessage> query(QueryMessage query, @Nullable ProcessingContext context) Description copied from interface:QueryBusConnectorSends the givenqueryto the remote QueryBus.- Specified by:
queryin interfaceQueryBusConnector- Parameters:
query- The query to send to the remote QueryBus.context- The context, if available, in which the query is generated- Returns:
- the stream of responses for the query
- See Also:
-
start
public void start()Prepares this connector for dispatching queries, after a previousshutdownDispatching()if any, and for answering subscriptions again, after a previousdisconnect()if any.Performed in the
Phase.INBOUND_QUERY_CONNECTORphase. -
disconnect
Stops advertising the queries this member handles, and tells the subscribers it is still answering that it is leaving.Performed in the
Phase.INBOUND_QUERY_CONNECTORphase, before dispatching is shut down, so that other members learn this member is leaving while it can still answer what is already in flight.Announcing it here is safe because shutdown reaches
Phase.INBOUND_EVENT_CONNECTORS, where event processors are stopped, before it reaches this phase. Nothing is left that could emit an update onto a subscription by the time they are ended, so no subscriber misses one. Where a web server would cut the subscriptions' streams before this phase, as Spring Boot's does, the announcement has to be made earlier; it is only made once, so the announcement here then finds nothing left to end.- Returns:
- a future that completes once this member no longer advertises any query, and answers no subscription
-
shutdownDispatching
Stops dispatching new queries, and waits for the responses to the ones already dispatched.Performed in the
Phase.OUTBOUND_QUERY_CONNECTORSphase.- Returns:
- a future that completes once every dispatched query has been answered
-
subscriptionQuery
public MessageStream<QueryResponseMessage> subscriptionQuery(QueryMessage query, @Nullable ProcessingContext context, int updateBufferSize) Description copied from interface:QueryBusConnectorSends the givenqueryto the remote QueryBus.- Specified by:
subscriptionQueryin interfaceQueryBusConnector- Parameters:
query- The query to send to the remote QueryBus.context- The context, if available, in which the query is generatedupdateBufferSize- The size of the buffer used to store update for the subscription query.- Returns:
- the stream of responses for the query
- See Also:
-
subscribe
Description copied from interface:QueryBusConnectorSubscribes this connector to queries matching the givenname.A connector serves queries of a given
namewith a single handler. Subscribing anamethis connector is already subscribed to therefore has no further effect, and completes as soon as the subscription that is already in place is acknowledged. A singleunsubscribeof thatnameundoes any number of subscriptions to it.- Specified by:
subscribein interfaceQueryBusConnector- Parameters:
queryName- TheQualifiedNameof theMessage.type()to subscribe to.- Returns:
- A
CompletableFuturethat completes successfully when this connector subscribed to the givenname.
-
unsubscribe
Description copied from interface:QueryBusConnectorUnsubscribes this connector from queries with the givenname.Undoes any number of
subscriptionsto the givenname, leaving no query of that name routed to this connector.- Specified by:
unsubscribein interfaceQueryBusConnector- Parameters:
queryName- TheQualifiedNameof theMessage.type()to unsubscribe from.- Returns:
trueif unsubscribing was successful,falseotherwise.
-
onIncomingQuery
Description copied from interface:QueryBusConnectorRegisters a handler to process incoming query messages.- Specified by:
onIncomingQueryin interfaceQueryBusConnector- Parameters:
handler- The handler responsible for managing incoming queries.
-
describeTo
Description copied from interface:DescribableComponentDescribe the properties ofthis DescribableComponentwith the givendescriptor.Components should call the appropriate
describePropertymethods on the descriptor to register their properties. The descriptor is responsible for determining how these properties are formatted and structured in the final output.Best Practices: As a general rule, all relevant fields of a
DescribableComponentimplementation should be described in this method. However, developers have discretion to include only the fields that make sense in the context. Not every field may be meaningful for description purposes, especially internal implementation details. Furthermore, components might want to expose different information based on their current state. The final decision on what properties to include lies with the person implementing thedescribeTomethod, who should focus on providing information that is useful for understanding the component's configuration and state.Example implementation:
public void describeTo(ComponentDescriptor descriptor) { descriptor.describeProperty("name", this.name); descriptor.describeProperty("enabled", this.enabled); descriptor.describeProperty("configuration", this.configuration); // A nested component descriptor.describeProperty("handlers", this.eventHandlers); // A collection }- Specified by:
describeToin interfaceDescribableComponent- Parameters:
descriptor- The component descriptor to describethis DescribableComponentn its properties in.
-