-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathProgram.cs
157 lines (132 loc) · 4.74 KB
/
Program.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
// Sagas - Hector Garcia-Molina & Kenneth Salem (1987)
// in docs folder
// Saga distributed transactions pattern
// https://learn.microsoft.com/en-us/azure/architecture/patterns/saga
// Pattern: Saga
// https://microservices.io/patterns/data/saga.html
class OrderService
{
public async Task CreateOrder(int orderId)
{
Console.WriteLine($"[OrderService] Order {orderId} has been created.");
await Task.Delay(500);
}
public async Task CancelOrder(int orderId)
{
Console.WriteLine($"[OrderService] Order {orderId} has been canceled.");
await Task.Delay(500);
}
}
class PaymentService
{
public async Task ProcessPayment(int orderId)
{
Console.WriteLine($"[PaymentService] Payment for Order {orderId} has been processed.");
await Task.Delay(500);
// Simulating a failure scenario
if (orderId % 2 == 0) throw new Exception("Payment processing failed!");
}
public async Task RefundPayment(int orderId)
{
Console.WriteLine($"[PaymentService] Payment for Order {orderId} has been refunded.");
await Task.Delay(500);
}
}
class InventoryService
{
public async Task UpdateInventory(int orderId)
{
Console.WriteLine($"[InventoryService] Inventory updated for Order {orderId}.");
await Task.Delay(500);
}
public async Task RestoreInventory(int orderId)
{
Console.WriteLine($"[InventoryService] Inventory restored for Order {orderId}.");
await Task.Delay(500);
}
}
class ShippingService
{
public async Task ShipOrder(int orderId)
{
Console.WriteLine($"[ShippingService] Order {orderId} has been shipped.");
await Task.Delay(500);
}
public async Task CancelShipment(int orderId)
{
Console.WriteLine($"[ShippingService] Shipment for Order {orderId} has been canceled.");
await Task.Delay(500);
}
}
class SagaOrchestrator
{
readonly OrderService _orderService = new();
readonly PaymentService _paymentService = new();
readonly InventoryService _inventoryService = new();
readonly ShippingService _shippingService = new();
readonly Stack<Func<Task>> _compensationStack = new();
public async Task<bool> ProcessOrderAsync(int orderId)
{
try
{
Console.WriteLine("SAGA: Order processing started...");
// Step 1: Create Order
await _orderService.CreateOrder(orderId);
_compensationStack.Push(() => _orderService.CancelOrder(orderId));
// Step 2: Process Payment
await _paymentService.ProcessPayment(orderId);
_compensationStack.Push(() => _paymentService.RefundPayment(orderId));
// Step 3: Update Inventory
await _inventoryService.UpdateInventory(orderId);
_compensationStack.Push(() => _inventoryService.RestoreInventory(orderId));
// Step 4: Initiate Shipping
await _shippingService.ShipOrder(orderId);
_compensationStack.Push(() => _shippingService.CancelShipment(orderId));
Console.WriteLine("SAGA: Order successfully completed!");
return true;
}
catch (Exception ex)
{
Console.WriteLine($"ERROR: {ex.Message}. Rolling back transactions...");
await Rollback();
return false;
}
}
private async Task Rollback()
{
while (_compensationStack.Count > 0)
{
var rollbackAction = _compensationStack.Pop();
await rollbackAction();
}
}
}
class Program
{
static async Task Main(string[] args)
{
var orchestrator = new SagaOrchestrator();
int orderId = 2; // Change this to test different scenarios
bool success = await orchestrator.ProcessOrderAsync(orderId);
Console.WriteLine(success ? "Order completed successfully!" : "Order failed, all transactions have been rolled back.");
/*
Failure Scenario (Payment Fails)
---
SAGA: Order processing started...
[OrderService] Order 2 has been created.
[PaymentService] Payment for Order 2 has been processed.
ERROR: Payment processing failed!. Rolling back transactions...
[OrderService] Order 2 has been canceled.
Order failed, all transactions have been rolled back.
Successful Order Processing
---
SAGA: Order processing started...
[OrderService] Order 1 has been created.
[PaymentService] Payment for Order 1 has been processed.
[InventoryService] Inventory updated for Order 1.
[ShippingService] Order 1 has been shipped.
SAGA: Order successfully completed!
Order completed successfully!
*/
}
}