Skip to content

Commit e71128f

Browse files
showcase UI changes (#100)
* show successful retry message * show note about retry time * tryitout styling * add link to giveaway after retry attempted * Wording * Updated link to giveaway * update default port * fix tab tile to match h1 --------- Co-authored-by: Udi Dahan <[email protected]>
1 parent baa7047 commit e71128f

File tree

15 files changed

+136
-23
lines changed

15 files changed

+136
-23
lines changed

src/Billing/SimulationEffects.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,10 @@ public async Task SimulateBillingProcessing(ConsumeContext<OrderPlaced> context)
3030
Interlocked.Increment(ref messagesErrored);
3131
throw new BillingProcessingException($"A simulated failure occurred in Billing, OrderId: {context.Message.OrderId}, Contents: {string.Join(", ", context.Message.Contents)}");
3232
}
33+
else if (isRetry)
34+
{
35+
await billingHub.Clients.All.SendAsync("RetrySuccessful", context.Message.OrderId);
36+
}
3337

3438
Interlocked.Increment(ref messagesProcessed);
3539
}

src/ClientUI/Program.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ public static IHostBuilder CreateHostBuilder(string[] args)
3838
services.AddSignalR(options => { options.EnableDetailedErrors = true; });
3939
services.AddSingleton<SimulatedCustomers>();
4040
});
41-
webBuilder.UseUrls($"http://*:{Environment.GetEnvironmentVariable("LISTENING_PORT") ?? "5000"}");
41+
webBuilder.UseUrls($"http://*:{Environment.GetEnvironmentVariable("LISTENING_PORT") ?? "5004"}");
4242
webBuilder.Configure(app =>
4343
{
4444
app.UseCors(options => options.AllowAnyHeader().AllowAnyMethod().WithOrigins("http://localhost:61335").AllowCredentials());

src/Sales/SimulationEffects.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,10 @@ public async Task SimulateSalesProcessing(ConsumeContext<PlaceOrder> context)
3030
Interlocked.Increment(ref messagesErrored);
3131
throw new SalesProcessingException($"A simulated failure occurred in Sales, OrderId: {context.Message.OrderId}, Contents: {string.Join(", ", context.Message.Contents)}");
3232
}
33+
else if (isRetry)
34+
{
35+
await salesHub.Clients.All.SendAsync("RetrySuccessful", context.Message.OrderId);
36+
}
3337

3438
Interlocked.Increment(ref messagesProcessed);
3539
}

src/Shipping/SimulationEffects.cs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,10 @@ public async Task SimulateOrderBilledProcessing(ConsumeContext<OrderBilled> cont
3434
Interlocked.Increment(ref orderBilledErrored);
3535
throw new OrderBilledException($"A simulated failure occurred in Shipping Order Billed handling, OrderId: {context.Message.OrderId}, Contents: {string.Join(", ", context.Message.Contents)}");
3636
}
37+
else if (isRetry)
38+
{
39+
await shippingHub.Clients.All.SendAsync("RetrySuccessfulOrderBilled", context.Message.OrderId);
40+
}
3741

3842
Interlocked.Increment(ref orderBilledProcessed);
3943
}
@@ -60,6 +64,10 @@ public async Task SimulateOrderPlacedProcessing(ConsumeContext<OrderPlaced> cont
6064
Interlocked.Increment(ref orderPlacedErrored);
6165
throw new OrderPlacedException($"A simulated failure occurred in Shipping Order Placed handling, OrderId: {context.Message.OrderId}, Contents: {string.Join(", ", context.Message.Contents)}");
6266
}
67+
else if (isRetry)
68+
{
69+
await shippingHub.Clients.All.SendAsync("RetrySuccessfulOrderPlaced", context.Message.OrderId);
70+
}
6371

6472
Interlocked.Increment(ref orderPlacedProcessed);
6573
}

src/frontend/index.html

Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,21 @@
11
<!DOCTYPE html>
22
<html lang="">
33
<head>
4-
<meta charset="UTF-8"/>
5-
<link rel="icon" href="/favicon.ico"/>
6-
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
7-
<title>MassTransit Message Retry Showcase</title>
4+
<meta charset="UTF-8" />
5+
<link rel="icon" href="/favicon.ico" />
6+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
7+
<title>MassTransit recoverability Showcase</title>
88
<!-- Google Tag Manager -->
99
<script>
1010
(function (w, d, s, l, i) {
1111
w[l] = w[l] || [];
12-
w[l].push({"gtm.start": new Date().getTime(), event: "gtm.js"});
12+
w[l].push({ "gtm.start": new Date().getTime(), event: "gtm.js" });
1313
var f = d.getElementsByTagName(s)[0],
1414
j = d.createElement(s),
15-
dl = l != "dataLayer"
16-
? "&l=" + l
17-
: "";
15+
dl = l != "dataLayer" ? "&l=" + l : "";
1816
j.async = true;
1917
j.src = "https://www.googletagmanager.com/gtm.js?id=" + i + dl;
20-
f
21-
.parentNode
22-
.insertBefore(j, f);
18+
f.parentNode.insertBefore(j, f);
2319
})(window, document, "script", "dataLayer", "GTM-N895C5BN ");
2420
</script>
2521
<!-- End Google Tag Manager -->
@@ -38,4 +34,4 @@
3834
<div id="app"></div>
3935
<script type="module" src="/src/main.ts"></script>
4036
</body>
41-
</html>
37+
</html>

src/frontend/src/App.vue

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import ShippingEndpoint from "./components/ShippingEndpoint.vue";
66
import TryItOut from "./components/guideline/TryItOut.vue";
77
import FloatingButton from "./components/FloatingButton.vue";
88
import { ref } from "vue";
9+
import { store } from "./components/shared";
910
1011
const tab = ref("showcase");
1112
</script>
@@ -32,6 +33,12 @@ const tab = ref("showcase");
3233
<div class="container">
3334
<div v-show="tab === 'showcase'">
3435
<h2>Simulating customers placing orders on a website</h2>
36+
<div v-if="store.messageRetried">
37+
Thanks for trying our showcase.
38+
<a href="https://gleam.io/ViON2/manning-ebook-giveaway">
39+
Get your free eBook now!
40+
</a>
41+
</div>
3542
<div class="architecture-diagram"></div>
3643
<div class="sections">
3744
<div><ClientEndpoint /></div>

src/frontend/src/assets/main.css

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,9 +38,9 @@ body {
3838

3939
/* Heading Styles */
4040
h2 {
41-
font-size: 1.8rem;
41+
font-size: 1.3rem;
4242
color: #2c3e50;
43-
margin-bottom: 1rem;
43+
margin-bottom: 0.5rem;
4444
}
4545

4646
.red {

src/frontend/src/components/BillingEndpoint.vue

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,17 @@ import { store } from "./shared";
1414
import MessageContainer from "./MessageContainer.vue";
1515
import { GA4 } from "../utils/analytics";
1616
17-
const {connection, state} = useSignalR(`http://${import.meta.env.VITE_BILLING_SIGNALR ?? "localhost:5002"}/billingHub`);
17+
const { connection, state } = useSignalR(
18+
`http://${
19+
import.meta.env.VITE_BILLING_SIGNALR ?? "localhost:5002"
20+
}/billingHub`
21+
);
1822
1923
const processedCount = ref(0);
2024
const erroredCount = ref(0);
2125
const shouldFailRetries = ref(false);
2226
const messages = ref<MessageOrError[]>([]);
27+
let retrySuccessful: string[] = [];
2328
2429
connection.on("ProcessingMessage", (order: Order) => {
2530
if (order) {
@@ -49,18 +54,31 @@ connection.on(
4954
connection.on("OrderBilled", (order: Order) => {
5055
if (order) {
5156
messages.value = [
52-
{ timestamp: new Date(), message: new OrderBilled(order) },
57+
{
58+
timestamp: new Date(),
59+
message: new OrderBilled(
60+
order,
61+
retrySuccessful.includes(order.orderId)
62+
),
63+
},
5364
...messages.value,
5465
].slice(0, Math.max(messages.value.length, 100));
5566
}
5667
});
5768
connection.on("RetryAttempted", () => {
5869
try {
70+
store.setMessageRetried();
5971
GA4.showcaseRetryAttempted();
6072
} catch (e) {
6173
console.error(e);
6274
}
6375
});
76+
connection.on("RetrySuccessful", (orderId: string) => {
77+
retrySuccessful = [orderId, ...retrySuccessful].slice(
78+
0,
79+
Math.max(messages.value.length, 100)
80+
);
81+
});
6482
6583
connection.on("SyncValues", (processed, errored, failRetries) => {
6684
processedCount.value = processed;
@@ -122,6 +140,9 @@ function toggleFailOnRetries() {
122140
{{ message.message.orderId }}
123141
</span>
124142
<span>billed</span>
143+
<span v-if="message.message.retrySuccessful" class="success">
144+
(After successful retry of OrderPlaced message)
145+
</span>
125146
</template>
126147
<template v-else>
127148
<span>Received order placed</span>

src/frontend/src/components/ClientEndpoint.vue

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,9 @@ import { store } from "./shared";
77
import type { PlaceOrder, Message } from "./types";
88
import MessageContainer from "./MessageContainer.vue";
99
10-
const { connection, state } = useSignalR(`http://${import.meta.env.VITE_CLIENT_SIGNALR ?? "localhost:5000"}/clientHub`);
10+
const { connection, state } = useSignalR(
11+
`http://${import.meta.env.VITE_CLIENT_SIGNALR ?? "localhost:5004"}/clientHub`
12+
);
1113
1214
const orderCount = ref(0);
1315
const messages = ref<Message[]>([]);
@@ -72,6 +74,10 @@ async function runScenario() {
7274
View Failures in ServicePulse
7375
</button>
7476
</a>
77+
<span class="note">
78+
NOTE: it may take several seconds after retrying a message for it to
79+
appear again in the consumer's input queue
80+
</span>
7581
</div>
7682
</div>
7783
<!-- <div class="or-line">
@@ -150,4 +156,8 @@ async function runScenario() {
150156
background-color: white;
151157
padding: 0 0.5em;
152158
}
159+
160+
.note {
161+
font-size: 0.85em;
162+
}
153163
</style>

src/frontend/src/components/MessageContainer.vue

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,11 @@ const props = defineProps<{
5353
font-weight: bold;
5454
}
5555
56+
:slotted(.message .success) {
57+
color: green;
58+
font-weight: bold;
59+
}
60+
5661
:slotted(.message .selected) {
5762
background-color: rgb(242, 152, 33);
5863
}

0 commit comments

Comments
 (0)