You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
@@ -115,7 +115,7 @@ The exact connector dependency depends on the runtime you are using. The connect
115
115
116
116
Depending on your runtime and packaging model, you may also need to make the Kafka client libraries available to the server or application classloader.
117
117
118
-
Refer to your runtime's documentation for the correct connector artifact coordinates, supported brokers, and configuration details. For a complete channel configuration example, see the <<_named_channels_for_message_flow>> section.
118
+
Refer to your runtime's documentation for the correct connector artifact coordinates, supported brokers, and configuration details. For a complete channel configuration example, see the <<named-channels-for-message-flow>> section.
119
119
120
120
== Defining Messaging Logic with CDI Beans
121
121
@@ -185,18 +185,25 @@ public class OrderStatusEventHandler {
185
185
@Inject
186
186
NotificationService notificationService;
187
187
188
+
@Inject
189
+
ManagedExecutor executor;
190
+
188
191
@Incoming("payment-authorized")
189
-
public void onPaymentAuthorized(Long orderId) {
190
-
Order updatedOrder = orderService.updateOrderStatus(orderId, OrderStatus.PAID);
* The `OrderStatusEventHandler` bean injects an `OrderService` for updating the persisted order and a `NotificationService` for sending payment confirmations.
199
-
* The `onPaymentAuthorized` method reacts to the `payment-authorized` channel, showing how the fulfillment workflow continues asynchronously after the initial REST checkout has completed.
205
+
* The `onPaymentAuthorized` method consumes the `Order` payload directly from the `payment-authorized` channel, matching the output type of the checkout producer pipeline.
206
+
* The method returns a `CompletionStage<Void>` and offloads the blocking database and notification work to a managed thread pool via `ManagedExecutor`. The underlying message broker will only acknowledge the message *after* this asynchronous processing successfully completes.
200
207
* This separation keeps the user-facing request/response path simple while moving cross-service processing into dedicated messaging handlers.
201
208
202
209
=== Scope Management in Messaging Beans
@@ -366,6 +373,10 @@ Use `Message<T>` when you need explicit acknowledgment control, access to metada
366
373
367
374
*4. Reactive Streams Processing*:
368
375
376
+
The MicroProfile Reactive Messaging specification is built on the *MicroProfile Reactive Streams Operators* specification and heavily utilizes `CompletionStage` for asynchronous operations. The core reactive types defined by the MicroProfile Reactive Messaging specification are the standard Reactive Streams interfaces: `Publisher<T>`, `Subscriber<T>`, and `Processor<T,R>`, along with their builder counterparts (`PublisherBuilder<T>`, `SubscriberBuilder<T>`, `ProcessorBuilder<T,R>`) from MicroProfile Reactive Streams Operators.
377
+
378
+
NOTE: Mutiny (`io.smallrye.mutiny`) is *not* part of the MicroProfile Reactive Messaging specification. It is the reactive library chosen by SmallRye Reactive Messaging (the reference implementation used by Quarkus). Because `Multi<T>` and `Uni<T>` implements the Reactive Streams `Publisher<T>` contract, it integrates seamlessly. However, you are free to use other reactive libraries. The examples in this chapter use Mutiny, but the patterns apply to any Reactive Streams-compatible type.
379
+
369
380
`Multi<T>` is a reactive type from the Mutiny library (`io.smallrye.mutiny.Multi`) that represents an asynchronous stream of zero or more items. It implements the Reactive Streams `Publisher<T>` contract and provides a rich set of operators for transforming, filtering, merging, and grouping streams in a composable, non-blocking way. Common operators include:
370
381
371
382
* `map(Function)` — transforms each item to a new value.
@@ -858,21 +869,30 @@ Process multiple messages concurrently while maintaining overall backpressure co
// Explicitly merge the Unis back into a Multi with a concurrency limit of 3
889
+
.merge(3);
872
890
}
873
891
----
874
892
875
-
The concurrency limit (3 in this example) ensures that no more than 3 messages are processed simultaneously. This provides controlled parallelism for I/O-bound operations while preventing resource exhaustion.
893
+
WARNING: Do not call `CompletableFuture.supplyAsync(() -> ...)` without an explicit executor. The no-argument overload submits work to the JVM-wide common `ForkJoinPool`, which is shared across the entire application, is sized for CPU-bound work, and carries no Jakarta EE context (security, transactions, `@RequestScoped` beans). In a MicroProfile application, always inject a `ManagedExecutorService` (from Jakarta Concurrency) and pass it as the second argument, or use Mutiny's `runSubscriptionOn(executor)` as shown above. Both approaches ensure proper container-managed thread execution and context propagation.
894
+
895
+
The concurrency limit (`3` in this example) ensures that no more than 3 messages are processed simultaneously. This provides controlled parallelism for I/O-bound operations while preventing resource exhaustion.
876
896
877
897
*Batching for Throughput*:
878
898
@@ -911,12 +931,12 @@ import java.time.Duration;
911
931
@Outgoing("rate-limited")
912
932
public Multi<Data> rateLimit(Multi<Data> stream) {
When MicroProfile Reactive Messaging 3.0.1 is used in an environment where MicroProfile Metrics is available, implementations automatically produce the following metrics in the `base` scope:
1044
+
When MicroProfile Reactive Messaging {reactive-messaging-spec-version} is used in an environment where MicroProfile Metrics is available, implementations automatically produce the following metrics in the `base` scope:
1025
1045
1026
1046
[cols="2,1,1,2"]
1027
1047
|===
@@ -1098,7 +1118,7 @@ Reliable message processing is ensured through multiple acknowledgment strategie
1098
1118
1099
1119
The specification's seamless integration with other MicroProfile specifications enhances the overall capabilities of reactive messaging applications. MicroProfile Fault Tolerance provides retry, circuit breaker, and timeout patterns for resilience; Config enables externalized configuration for different environments; Metrics supports both automatic and custom observability; Health integrates with Kubernetes for readiness probes; and OpenAPI documents REST endpoints that bridge to messaging systems. The connector ecosystem, supporting Kafka, AMQP, JMS, and other brokers, handles protocol-specific details, serialization, and connection management, freeing applications to focus purely on message processing logic.
1100
1120
1101
-
To continue your journey with MicroProfile Reactive Messaging, explore the complete https://download.eclipse.org/microprofile/microprofile-reactive-messaging-3.0.1/microprofile-reactive-messaging-spec-3.0.1.html[MicroProfile Reactive Messaging 3.0.1 Specification] for detailed API documentation and conformance requirements. Study connector-specific features for your chosen message broker in your runtime's documentation. Leverage the integration points with other MicroProfile specifications such as Fault Tolerance for resilience, Config for externalization, Metrics for observability, and Health for container orchestration.
1121
+
To continue your journey with MicroProfile Reactive Messaging, explore the complete https://download.eclipse.org/microprofile/microprofile-reactive-messaging-{reactive-messaging-spec-version}/microprofile-reactive-messaging-spec-{reactive-messaging-spec-version}.html[MicroProfile Reactive Messaging {reactive-messaging-spec-version} Specification] for detailed API documentation and conformance requirements. Study connector-specific features for your chosen message broker in your runtime's documentation. Leverage the integration points with other MicroProfile specifications such as Fault Tolerance for resilience, Config for externalization, Metrics for observability, and Health for container orchestration.
1102
1122
1103
1123
By mastering these concepts and patterns, you can build modern, reactive microservices that handle high-volume data streams efficiently and reliably in production environments, taking full advantage of the reactive programming model to create responsive, resilient, and scalable distributed systems.
0 commit comments