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
Copy file name to clipboardExpand all lines: docs/aac/java-mwa-guide.md
+49-16Lines changed: 49 additions & 16 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -117,33 +117,66 @@ Use the [Strangler fig](/azure/architecture/patterns/strangler-fig) pattern to g
117
117
118
118
Implement the [Queue-Based Load Leveling pattern](/azure/architecture/patterns/queue-based-load-leveling) on producer portion of the decoupled service to asynchronously handle tasks that don't need immediate responses. This pattern enhances overall system responsiveness and scalability by using a queue to manage workload distribution. It allows the decoupled service to process requests at a consistent rate. To implement this pattern effectively, follow these recommendations:
119
119
120
-
-*Use nonblocking message queuing.* Ensure the process that sends messages to the queue doesn't block other processes while waiting for the decoupled service to handle messages in the queue. If the process requires the result of the decoupled-service operation, have an alternative way to handle the situation while waiting for the queued operation to complete. For example, the reference implementation uses Azure Service Bus and the `await` keyword with `messageSender.PublishAsync()` to asynchronously publish messages to the queue without blocking the thread that executes this code (*see example code*):
120
+
-*Use non-blocking message queuing.* Ensure the process that sends messages to the queue doesn't block other processes while waiting for the decoupled service to handle messages in the queue. If the process requires the result of the decoupled-service operation, implement an alternative way to handle the situation while waiting for the queued operation to complete. For example, in Spring Boot, you can use the `StreamBridge` class to asynchronously publish messages to the queue without blocking the calling thread (*see example code*):
121
+
122
+
```java
123
+
privatefinalStreamBridge streamBridge;
124
+
125
+
public SupportGuideQueueSender(StreamBridge streamBridge) {
126
+
this.streamBridge = streamBridge;
127
+
}
121
128
122
-
```csharp
123
129
// Asynchronously publish a message without blocking the calling thread
ThisJava example uses `StreamBridge` to send messages asynchronously
148
+
127
149
This approach ensures that the main application remains responsive and can handle other tasks concurrently, while the decoupled service processes the queued requests at a manageable rate.
128
150
129
151
-*Implement message retry and removal.*Implement a mechanism to retry processing of queued messages that can't be processed successfully. If failures persist, these messages should be removed from the queue. For example, Azure Service Bus has built-in retry and dead letter queue features.
130
152
131
-
-*Configureidempotentmessageprocessing.*Thelogicthatprocessesmessagesfromthequeuemustbeidempotenttohandlecaseswhereamessagemightbeprocessedmorethanonce. Forexample, thereferenceimplementationuses `ServiceBusClient.CreateProcessor` with`AutoCompleteMessages=true` and `ReceiveMode=ServiceBusReceiveMode.PeekLock` toensuremessagesareonlyprocessedonceandcanbereprocessedonfailure(*seefollowingcode*).
153
+
- *Configure idempotent message processing.* The logic that processes messages from the queue must be idempotent to handle cases where a message might be processed more than once. In Spring Boot, you can use `@StreamListener` or `@KafkaListener` with a unique message identifier to prevent duplicate processing. Or you can organize the business process o operate in a functional approach with Spring Cloud Stream, where the `consume` method is defined in a way that produces the same result when it is executed repeatedly (*see example code*):
132
154
133
-
```csharp
134
-
// Create a processor for idempotent message processing
.setMessage("Email sent to " + emailRequest.getEmailAddress() + " with URL to manual " + emailRequest.getUrlToManual())
170
+
.setStatus(Status.SUCCESS)
171
+
.build();
172
+
173
+
return emailResponse.toByteArray();
174
+
175
+
} catch (InvalidProtocolBufferException e) {
176
+
throw new RuntimeException("Error parsing email request message", e);
177
+
}
178
+
};
179
+
}
147
180
```
148
181
149
182
- *Manage changes to the experience.* Asynchronous processing can lead to tasks not being immediately completed. Users should be made aware when their task is still being processed to set correct expectations and avoid confusion. Use visual cues or messages to indicate that a task is in progress. Give users the option to receive notifications when their task is done, such as an email or push notification.
0 commit comments