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
@@ -316,6 +317,7 @@ Some messaging technologies allow consumers to subscribe to a set of topics or q
316
317
If you are sure you need to configure and create clients dynamically at runtime, you should consider using the low-level clients directly.
317
318
====
318
319
320
+
[[internal-channels]]
319
321
==== Internal Channels
320
322
321
323
In some use cases, it is convenient to use messaging patterns to transfer messages inside the same application.
@@ -562,6 +564,7 @@ public class StreamProcessor {
562
564
}
563
565
----
564
566
567
+
[[execution_model]]
565
568
== Execution Model
566
569
567
570
Quarkus Messaging sits on top of the xref:quarkus-reactive-architecture.adoc#engine[reactive engine] of Quarkus and leverages link:{eclipse-vertx}[Eclipse Vert.x] to dispatch messages for processing.
@@ -634,6 +637,163 @@ Depending on the broker technology, this can be useful to increase the applicati
634
637
while still preserving the partial order of messages received in different copies.
635
638
This is the case, for example, for Kafka, where multiple consumers can consume different topic partitions.
636
639
640
+
== Context Propagation
641
+
642
+
In Quarkus Messaging, the default mechanism for propagating context between different processing stages is the
This provides a consistent way to pass context information along with the message as it flows through different stages.
645
+
646
+
When integrating with other extensions, notably using Emitters, it relies on the Mutiny context propagation:
647
+
648
+
=== Interaction with Mutiny and MicroProfile Context Propagation
649
+
650
+
Mutiny, which is the foundation of reactive programming in Quarkus, is integrated with the MicroProfile Context Propagation.
651
+
This integration enables automatic capturing and restoring of context across asynchronous boundaries.
652
+
To learn more about context propagation in Quarkus and Mutiny, refer to the xref:context-propagation.adoc[Context Propagation] guide.
653
+
654
+
To ensure consistent behavior, Quarkus Messaging disables the propagation of any context during message dispatching through inbound or outbound connectors.
655
+
This means that context captured through Emitters won't be propagated to the outgoing channel, and incoming channels won't dispatch messages by activating a context (e.g. the request context).
656
+
This behaviour can be configured using `quarkus.messaging.connector-context-propagation` configuration property, by listing the context types to propagate.
657
+
For example `quarkus.messaging.connector-context-propagation=CDI` will only propagate the CDI context.
658
+
659
+
<<internal-channels>> however do propagate the context, as they are part of the same application and the context is not lost.
660
+
661
+
For example, you might want to propagate the caller context from an incoming HTTP request to the message processing stage.
662
+
For emitters, it is recommended to use the `MutinyEmitter`, as it exposes methods such as `sendAndAwait` that makes sure to wait until a message processing is terminated.
663
+
664
+
[WARNING]
665
+
====
666
+
The execution context to which the RequestScoped context is bound, in the previous example the REST call, controls the lifecycle of the context.
667
+
This means that when the REST call is completed the RequestScoped context is destroyed.
668
+
Therefore, you need to make sure that your processing or message dispatch is completed before the REST call completes.
669
+
670
+
For more information check the xref:context-propagation.adoc#context-propagation-for-cdi[Context Propagation] guide.
671
+
====
672
+
673
+
For example, let `RequestScopedBean` a request-scoped bean, `MutinyEmitter` can be used to dispatch messages locally through the internal channel `app`:
Log.infof("Message %s from request %s", message, requestScopedBean.getValue());
734
+
}
735
+
736
+
}
737
+
----
738
+
739
+
[TIP]
740
+
====
741
+
You can use the context propagation annotation `@CurrentThreadContext` to configure the contexts that will be propagated from an _emitter_ method.
742
+
The annotation configures the contexts that will be captured and propagated from that method,
743
+
and needs to be present on the propagator method, i.e. the caller of the emitter, not the processing method.
744
+
745
+
Because Quarkus Messaging dispatches messages on link:https://smallrye.io/smallrye-reactive-messaging/latest/concepts/message-context[message context],
746
+
propagation plans with cleared or not propagated contexts can lead to race conditions using emitters in <<internal-channels,internal channels>>.
747
+
It is recommended to use `ContextualEmitter` to ensure the context propagation plan is applied correctly.
748
+
749
+
The following example shows how to avoid propagating any context to the message processing stage:
In some cases, you might need to activate the request context while processing messages consumed from a broker.
793
+
While using `@ActivateRequestContext` on the `@Incoming` method is an option, its lifecycle does not follow that of a Quarkus Messaging message.
794
+
For incoming channels, you can enable the request scope activation with the build time property `quarkus.messaging.request-scoped.enabled=true`.
795
+
This will activate the request context for each message processed by incoming channels, and close the context once the message is processed.
796
+
637
797
== Health Checks
638
798
639
799
Together with the SmallRye Health extension, Quarkus Messaging extensions provide health check support per channel.
@@ -868,9 +1028,39 @@ The `quarkus-test-vertx` dependency provides the `@io.quarkus.test.vertx.RunOnVe
868
1028
869
1029
If your tests are dependent on context propagation, you can configure the in-memory connector channels with `run-on-vertx-context` attribute to dispatch events, including messages and acknowledgements, on a Vert.x context.
870
1030
Alternatively you can switch this behaviour using the `InMemorySource#runOnVertxContext` method.
871
-
872
1031
====
873
1032
1033
+
=== Channel Decorators
1034
+
1035
+
https://smallrye.io/smallrye-reactive-messaging/latest/concepts/decorators/[Channel decorators] is a way to intercept and decorate the reactive streams corresponding to messaging channels.
1036
+
This can be useful for adding custom behavior to the channels, such as logging, metrics, or error handling.
1037
+
1038
+
It is therefore possible to implement a bean implementing `PublisherDecorator` for incoming channels, and `SubscriberDecorator` for outgoing channels.
1039
+
Since two APIs are symmetric, you can implement both interfaces in the same bean.
1040
+
These beans are automatically discovered by Quarkus and applied by priority (from the least value to the greatest).
1041
+
1042
+
Some decorators are included by default by Quarkus extensions.
1043
+
1044
+
Incoming channels (PublisherDecorator) in the order of priority:
1045
+
1046
+
- `io.quarkus.smallrye.reactivemessaging.runtime.ConnectorContextPropagationDecorator` (-100): Clears the context propagation for incoming channels
1047
+
- `io.smallrye.reactive.messaging.providers.locals.ContextDecorator` (0): Ensures messages are dispatched on the message context
- `io.quarkus.opentelemetry.runtime.tracing.intrumentation.reactivemessaging.ReactiveMessagingTracingIncomingDecorator` (1000): Included with `quarkus-opentelemetry` extension, propagates tracing information
1055
+
1056
+
Outgoing channels (SubscriberDecorator):
1057
+
1058
+
- `io.quarkus.smallrye.reactivemessaging.runtime.ConnectorContextPropagationDecorator` (-100): Clears the context propagation for outgoing channels
1059
+
- `io.smallrye.reactive.messaging.providers.extension.OutgoingObservationDecorator` (1000): Message observation support for outgoing channels
- `io.quarkus.opentelemetry.runtime.tracing.intrumentation.reactivemessaging.ReactiveMessagingTracingOutgoingDecorator` (1000): Included with `quarkus-opentelemetry` extension, propagates tracing information
Copy file name to clipboardExpand all lines: extensions/smallrye-reactive-messaging-kafka/deployment/src/main/java/io/quarkus/smallrye/reactivemessaging/kafka/deployment/DotNames.java
Copy file name to clipboardExpand all lines: extensions/smallrye-reactive-messaging-kafka/deployment/src/main/java/io/quarkus/smallrye/reactivemessaging/kafka/deployment/SmallRyeReactiveMessagingKafkaProcessor.java
+8-1Lines changed: 8 additions & 1 deletion
Original file line number
Diff line number
Diff line change
@@ -538,7 +538,7 @@ private Type getOutgoingTypeFromChannelInjectionPoint(Type injectionPointType) {
538
538
returnnull;
539
539
}
540
540
541
-
if (isEmitter(injectionPointType) || isMutinyEmitter(injectionPointType)
541
+
if (isEmitter(injectionPointType) || isMutinyEmitter(injectionPointType) || isContextualEmitter(injectionPointType)
Copy file name to clipboardExpand all lines: extensions/smallrye-reactive-messaging-pulsar/deployment/src/main/java/io/quarkus/smallrye/reactivemessaging/pulsar/deployment/DotNames.java
Copy file name to clipboardExpand all lines: extensions/smallrye-reactive-messaging-pulsar/deployment/src/main/java/io/quarkus/smallrye/reactivemessaging/pulsar/deployment/PulsarSchemaDiscoveryProcessor.java
+9-1Lines changed: 9 additions & 1 deletion
Original file line number
Diff line number
Diff line change
@@ -300,7 +300,8 @@ private Type getOutgoingTypeFromChannelInjectionPoint(Type injectionPointType) {
300
300
returnnull;
301
301
}
302
302
303
-
if (isEmitter(injectionPointType) || isMutinyEmitter(injectionPointType) || isPulsarEmitter(injectionPointType)) {
303
+
if (isEmitter(injectionPointType) || isMutinyEmitter(injectionPointType)
Copy file name to clipboardExpand all lines: extensions/smallrye-reactive-messaging/deployment/src/main/java/io/quarkus/smallrye/reactivemessaging/deployment/ReactiveMessagingBuildTimeConfig.java
+7Lines changed: 7 additions & 0 deletions
Original file line number
Diff line number
Diff line change
@@ -27,4 +27,11 @@ public interface ReactiveMessagingBuildTimeConfig {
27
27
@WithName("auto-connector-attachment")
28
28
@WithDefault("true")
29
29
booleanautoConnectorAttachment();
30
+
31
+
/**
32
+
* Whether to enable the RequestScope context on a message context
Copy file name to clipboardExpand all lines: extensions/smallrye-reactive-messaging/deployment/src/main/java/io/quarkus/smallrye/reactivemessaging/deployment/SmallRyeReactiveMessagingProcessor.java
0 commit comments