-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #2 from Particular/add-clientui
Add Main UI projects
Showing
31 changed files
with
801 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
/binaries/**/* |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
[*.cs] | ||
|
||
# Justification: Test project | ||
dotnet_diagnostic.CA2007.severity = none | ||
|
||
# Justification: Tests don't support cancellation and don't need to forward IMessageHandlerContext.CancellationToken | ||
dotnet_diagnostic.NSB0002.severity = suggestion |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
<Project Sdk="Microsoft.NET.Sdk"> | ||
|
||
<PropertyGroup> | ||
<TargetFramework>net8.0</TargetFramework> | ||
<OutputType>Exe</OutputType> | ||
<ImplicitUsings>enable</ImplicitUsings> | ||
<Nullable>enable</Nullable> | ||
<OutputPath>..\binaries\Billing\</OutputPath> | ||
<ApplicationIcon>failures.ico</ApplicationIcon> | ||
</PropertyGroup> | ||
|
||
<ItemGroup> | ||
<ProjectReference Include="..\Messages\Messages.csproj" /> | ||
</ItemGroup> | ||
|
||
<ItemGroup> | ||
<PackageReference Include="MassTransit.RabbitMQ" Version="8.2.3" /> | ||
<PackageReference Include="Microsoft.Extensions.Hosting" Version="8.0.0" /> | ||
</ItemGroup> | ||
</Project> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
namespace Billing; | ||
|
||
using System.Threading.Tasks; | ||
using MassTransit; | ||
using Messages; | ||
|
||
public class OrderPlacedHandler(SimulationEffects simulationEffects) : IConsumer<OrderPlaced> | ||
{ | ||
public async Task Consume(ConsumeContext<OrderPlaced> context) | ||
{ | ||
await simulationEffects.SimulatedMessageProcessing(context.CancellationToken); | ||
|
||
var orderBilled = new OrderBilled | ||
{ | ||
OrderId = context.Message.OrderId | ||
}; | ||
|
||
await context.Publish(orderBilled); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
#pragma warning disable IDE0010 | ||
namespace Billing; | ||
|
||
using Microsoft.Extensions.Hosting; | ||
using MassTransit; | ||
using Microsoft.Extensions.DependencyInjection; | ||
using System.Reflection; | ||
|
||
class Program | ||
{ | ||
public static IHostBuilder CreateHostBuilder(string[] args) | ||
{ | ||
var host = Host.CreateDefaultBuilder(args) | ||
.ConfigureServices((hostContext, services) => | ||
{ | ||
services.AddMassTransit(x => | ||
{ | ||
x.UsingRabbitMq((context, cfg) => | ||
{ | ||
cfg.Host("localhost", "/", h => | ||
{ | ||
h.Username("guest"); | ||
h.Password("guest"); | ||
}); | ||
|
||
cfg.ConfigureEndpoints(context); | ||
}); | ||
|
||
x.AddConfigureEndpointsCallback((name, cfg) => | ||
{ | ||
if (cfg is IRabbitMqReceiveEndpointConfigurator rmq) | ||
{ | ||
rmq.SetQuorumQueue(); | ||
} | ||
}); | ||
|
||
x.AddConsumers(Assembly.GetExecutingAssembly()); | ||
}); | ||
|
||
services.AddSingleton<SimulationEffects>(); | ||
}); | ||
|
||
return host; | ||
} | ||
|
||
static async Task Main(string[] args) | ||
{ | ||
Console.Title = "Failure rate (Billing)"; | ||
Console.SetWindowSize(65, 15); | ||
|
||
var host = CreateHostBuilder(args).Build(); | ||
await host.StartAsync(); | ||
|
||
var state = host.Services.GetRequiredService<SimulationEffects>(); | ||
await RunUserInterfaceLoop(state); | ||
} | ||
|
||
static Task RunUserInterfaceLoop(SimulationEffects state) | ||
{ | ||
while (true) | ||
{ | ||
Console.Clear(); | ||
Console.WriteLine("Billing Endpoint"); | ||
Console.WriteLine("Press F to increase the simulated failure rate"); | ||
Console.WriteLine("Press S to decrease the simulated failure rate"); | ||
Console.WriteLine("Press ESC to quit"); | ||
Console.WriteLine(); | ||
|
||
state.WriteState(Console.Out); | ||
|
||
var input = Console.ReadKey(true); | ||
|
||
switch (input.Key) | ||
{ | ||
case ConsoleKey.F: | ||
state.IncreaseFailureRate(); | ||
break; | ||
case ConsoleKey.S: | ||
state.DecreaseFailureRate(); | ||
break; | ||
case ConsoleKey.Escape: | ||
return Task.CompletedTask; | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
namespace Billing; | ||
|
||
public class SimulationEffects | ||
{ | ||
public void IncreaseFailureRate() => failureRate = Math.Min(1, failureRate + FailureRateIncrement); | ||
|
||
public void DecreaseFailureRate() => failureRate = Math.Max(0, failureRate - FailureRateIncrement); | ||
|
||
public void WriteState(TextWriter output) => output.WriteLine("Failure rate: {0:P0}", failureRate); | ||
|
||
public async Task SimulatedMessageProcessing(CancellationToken cancellationToken = default) | ||
{ | ||
await Task.Delay(200, cancellationToken); | ||
|
||
if (Random.Shared.NextDouble() < failureRate) | ||
{ | ||
throw new Exception("BOOM! A failure occurred"); | ||
} | ||
} | ||
|
||
double failureRate; | ||
const double FailureRateIncrement = 0.1; | ||
} |
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
[*.cs] | ||
|
||
# Justification: Test project | ||
dotnet_diagnostic.CA2007.severity = none | ||
|
||
# Justification: Tests don't support cancellation and don't need to forward IMessageHandlerContext.CancellationToken | ||
dotnet_diagnostic.NSB0002.severity = suggestion |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
<Project Sdk="Microsoft.NET.Sdk"> | ||
|
||
<PropertyGroup> | ||
<TargetFramework>net8.0</TargetFramework> | ||
<OutputType>Exe</OutputType> | ||
<ImplicitUsings>enable</ImplicitUsings> | ||
<Nullable>enable</Nullable> | ||
<OutputPath>..\binaries\ClientUI\</OutputPath> | ||
<ApplicationIcon>traffic.ico</ApplicationIcon> | ||
</PropertyGroup> | ||
|
||
<ItemGroup> | ||
<PackageReference Include="MassTransit.RabbitMQ" Version="8.2.3" /> | ||
<PackageReference Include="Microsoft.Extensions.Hosting" Version="8.0.0" /> | ||
</ItemGroup> | ||
|
||
<ItemGroup> | ||
<ProjectReference Include="..\Messages\Messages.csproj" /> | ||
</ItemGroup> | ||
</Project> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
#pragma warning disable IDE0010 | ||
namespace ClientUI; | ||
|
||
using Microsoft.Extensions.Hosting; | ||
using MassTransit; | ||
using Microsoft.Extensions.DependencyInjection; | ||
using System.Reflection; | ||
|
||
class Program | ||
{ | ||
public static IHostBuilder CreateHostBuilder(string[] args) | ||
{ | ||
var host = Host.CreateDefaultBuilder(args) | ||
.ConfigureServices((_, services) => | ||
{ | ||
services.AddMassTransit(x => | ||
{ | ||
x.UsingRabbitMq((context, cfg) => | ||
{ | ||
cfg.Host("localhost", "/", h => | ||
{ | ||
h.Username("guest"); | ||
h.Password("guest"); | ||
}); | ||
|
||
cfg.ConfigureEndpoints(context); | ||
}); | ||
|
||
x.AddConfigureEndpointsCallback((name, cfg) => | ||
{ | ||
if (cfg is IRabbitMqReceiveEndpointConfigurator rmq) | ||
{ | ||
rmq.SetQuorumQueue(); | ||
} | ||
}); | ||
|
||
x.AddConsumers(Assembly.GetExecutingAssembly()); | ||
}); | ||
|
||
services.AddSingleton<SimulatedCustomers>(); | ||
services.AddHostedService(p => p.GetRequiredService<SimulatedCustomers>()); | ||
}); | ||
|
||
return host; | ||
} | ||
|
||
static async Task Main(string[] args) | ||
{ | ||
Console.Title = "Load (ClientUI)"; | ||
Console.SetWindowSize(65, 15); | ||
|
||
var host = CreateHostBuilder(args).Build(); | ||
await host.StartAsync(); | ||
|
||
var customers = host.Services.GetRequiredService<SimulatedCustomers>(); | ||
|
||
await RunUserInterfaceLoop(customers); | ||
} | ||
|
||
static Task RunUserInterfaceLoop(SimulatedCustomers simulatedCustomers) | ||
{ | ||
while (true) | ||
{ | ||
Console.Clear(); | ||
Console.WriteLine("Simulating customers placing orders on a website"); | ||
Console.WriteLine("Press T to toggle High/Low traffic mode"); | ||
Console.WriteLine("Press ESC to quit"); | ||
Console.WriteLine(); | ||
|
||
simulatedCustomers.WriteState(Console.Out); | ||
|
||
var input = Console.ReadKey(true); | ||
|
||
switch (input.Key) | ||
{ | ||
case ConsoleKey.T: | ||
simulatedCustomers.ToggleTrafficMode(); | ||
break; | ||
case ConsoleKey.Escape: | ||
return Task.CompletedTask; | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
namespace ClientUI; | ||
|
||
using MassTransit; | ||
using Messages; | ||
using Microsoft.Extensions.Hosting; | ||
|
||
class SimulatedCustomers(IBus _bus) : BackgroundService | ||
{ | ||
public void WriteState(TextWriter output) | ||
{ | ||
var trafficMode = highTrafficMode ? "High" : "Low"; | ||
output.WriteLine($"{trafficMode} traffic mode - sending {rate} orders / second"); | ||
} | ||
|
||
public void ToggleTrafficMode() | ||
{ | ||
highTrafficMode = !highTrafficMode; | ||
rate = highTrafficMode ? HightTrafficRate : LowTrafficRate; | ||
} | ||
|
||
Task PlaceSingleOrder(CancellationToken cancellationToken) | ||
{ | ||
var placeOrderCommand = new PlaceOrder | ||
{ | ||
OrderId = Guid.NewGuid().ToString() | ||
}; | ||
|
||
return _bus.Publish(placeOrderCommand, cancellationToken); | ||
} | ||
|
||
protected override async Task ExecuteAsync(CancellationToken cancellationToken) | ||
{ | ||
nextReset = DateTime.UtcNow.AddSeconds(1); | ||
currentIntervalCount = 0; | ||
|
||
while (!cancellationToken.IsCancellationRequested) | ||
{ | ||
var now = DateTime.UtcNow; | ||
if (now > nextReset) | ||
{ | ||
currentIntervalCount = 0; | ||
nextReset = now.AddSeconds(1); | ||
} | ||
|
||
await PlaceSingleOrder(cancellationToken); | ||
currentIntervalCount++; | ||
|
||
try | ||
{ | ||
if (currentIntervalCount >= rate) | ||
{ | ||
var delay = nextReset - DateTime.UtcNow; | ||
if (delay > TimeSpan.Zero) | ||
{ | ||
await Task.Delay(delay, cancellationToken); | ||
} | ||
} | ||
} | ||
catch (TaskCanceledException) | ||
{ | ||
break; | ||
} | ||
} | ||
} | ||
|
||
bool highTrafficMode; | ||
|
||
DateTime nextReset; | ||
int currentIntervalCount; | ||
int rate = LowTrafficRate; | ||
|
||
const int HightTrafficRate = 8; | ||
const int LowTrafficRate = 1; | ||
} |
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
Microsoft Visual Studio Solution File, Format Version 12.00 | ||
# Visual Studio Version 17 | ||
VisualStudioVersion = 17.9.34902.65 | ||
MinimumVisualStudioVersion = 15.0.26730.12 | ||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{7D29C905-CE3A-4D93-8271-7BA09CEE1631}" | ||
ProjectSection(SolutionItems) = preProject | ||
Directory.Build.props = Directory.Build.props | ||
EndProjectSection | ||
EndProject | ||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ClientUI", "ClientUI\ClientUI.csproj", "{918001C1-B9F6-4E81-894B-128271E8D910}" | ||
EndProject | ||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Messages", "Messages\Messages.csproj", "{CFF586B0-0FA1-4F3C-B860-44BE86B0F341}" | ||
EndProject | ||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Sales", "Sales\Sales.csproj", "{6AD27F13-8B6B-4851-BBB8-A93D7FE463D9}" | ||
EndProject | ||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Billing", "Billing\Billing.csproj", "{709E5DF7-B76F-4FA6-BCB3-EF0C43C51FC6}" | ||
EndProject | ||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Shipping", "Shipping\Shipping.csproj", "{457FCA71-C1D9-43FF-838A-825A47E9E112}" | ||
EndProject | ||
Global | ||
GlobalSection(SolutionConfigurationPlatforms) = preSolution | ||
Debug|Any CPU = Debug|Any CPU | ||
Release|Any CPU = Release|Any CPU | ||
EndGlobalSection | ||
GlobalSection(ProjectConfigurationPlatforms) = postSolution | ||
{918001C1-B9F6-4E81-894B-128271E8D910}.Debug|Any CPU.ActiveCfg = Debug|Any CPU | ||
{918001C1-B9F6-4E81-894B-128271E8D910}.Debug|Any CPU.Build.0 = Debug|Any CPU | ||
{918001C1-B9F6-4E81-894B-128271E8D910}.Release|Any CPU.ActiveCfg = Release|Any CPU | ||
{918001C1-B9F6-4E81-894B-128271E8D910}.Release|Any CPU.Build.0 = Release|Any CPU | ||
{CFF586B0-0FA1-4F3C-B860-44BE86B0F341}.Debug|Any CPU.ActiveCfg = Debug|Any CPU | ||
{CFF586B0-0FA1-4F3C-B860-44BE86B0F341}.Debug|Any CPU.Build.0 = Debug|Any CPU | ||
{CFF586B0-0FA1-4F3C-B860-44BE86B0F341}.Release|Any CPU.ActiveCfg = Release|Any CPU | ||
{CFF586B0-0FA1-4F3C-B860-44BE86B0F341}.Release|Any CPU.Build.0 = Release|Any CPU | ||
{6AD27F13-8B6B-4851-BBB8-A93D7FE463D9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU | ||
{6AD27F13-8B6B-4851-BBB8-A93D7FE463D9}.Debug|Any CPU.Build.0 = Debug|Any CPU | ||
{6AD27F13-8B6B-4851-BBB8-A93D7FE463D9}.Release|Any CPU.ActiveCfg = Release|Any CPU | ||
{6AD27F13-8B6B-4851-BBB8-A93D7FE463D9}.Release|Any CPU.Build.0 = Release|Any CPU | ||
{709E5DF7-B76F-4FA6-BCB3-EF0C43C51FC6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU | ||
{709E5DF7-B76F-4FA6-BCB3-EF0C43C51FC6}.Debug|Any CPU.Build.0 = Debug|Any CPU | ||
{709E5DF7-B76F-4FA6-BCB3-EF0C43C51FC6}.Release|Any CPU.ActiveCfg = Release|Any CPU | ||
{709E5DF7-B76F-4FA6-BCB3-EF0C43C51FC6}.Release|Any CPU.Build.0 = Release|Any CPU | ||
{457FCA71-C1D9-43FF-838A-825A47E9E112}.Debug|Any CPU.ActiveCfg = Debug|Any CPU | ||
{457FCA71-C1D9-43FF-838A-825A47E9E112}.Debug|Any CPU.Build.0 = Debug|Any CPU | ||
{457FCA71-C1D9-43FF-838A-825A47E9E112}.Release|Any CPU.ActiveCfg = Release|Any CPU | ||
{457FCA71-C1D9-43FF-838A-825A47E9E112}.Release|Any CPU.Build.0 = Release|Any CPU | ||
EndGlobalSection | ||
GlobalSection(SolutionProperties) = preSolution | ||
HideSolutionNode = FALSE | ||
EndGlobalSection | ||
GlobalSection(ExtensibilityGlobals) = postSolution | ||
SolutionGuid = {081FC59E-04F4-4FB2-88A6-64A7C18BAA10} | ||
EndGlobalSection | ||
EndGlobal |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
[*.cs] | ||
|
||
# Justification: Test project | ||
dotnet_diagnostic.CA2007.severity = none | ||
|
||
# Justification: Tests don't support cancellation and don't need to forward IMessageHandlerContext.CancellationToken | ||
dotnet_diagnostic.NSB0002.severity = suggestion |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
<Project Sdk="Microsoft.NET.Sdk"> | ||
|
||
<PropertyGroup> | ||
<TargetFramework>net8.0</TargetFramework> | ||
<ImplicitUsings>enable</ImplicitUsings> | ||
<Nullable>enable</Nullable> | ||
</PropertyGroup> | ||
|
||
</Project> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
namespace Messages; | ||
|
||
public class OrderBilled | ||
{ | ||
public string? OrderId { get; set; } | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
namespace Messages; | ||
|
||
public class OrderPlaced | ||
{ | ||
public string? OrderId { get; set; } | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
namespace Messages; | ||
|
||
public class PlaceOrder | ||
{ | ||
public string? OrderId { get; set; } | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
[*.cs] | ||
|
||
# Justification: Test project | ||
dotnet_diagnostic.CA2007.severity = none | ||
|
||
# Justification: Tests don't support cancellation and don't need to forward IMessageHandlerContext.CancellationToken | ||
dotnet_diagnostic.NSB0002.severity = suggestion |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
namespace Sales; | ||
|
||
using Messages; | ||
using MassTransit; | ||
using System.Threading.Tasks; | ||
|
||
public class PlaceOrderHandler(SimulationEffects simulationEffects) : IConsumer<PlaceOrder> | ||
{ | ||
public async Task Consume(ConsumeContext<PlaceOrder> context) | ||
{ | ||
// Simulate the time taken to process a message | ||
await simulationEffects.SimulateMessageProcessing(context.CancellationToken); | ||
|
||
var orderPlaced = new OrderPlaced | ||
{ | ||
OrderId = context.Message.OrderId | ||
}; | ||
|
||
await context.Publish(orderPlaced); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,89 @@ | ||
#pragma warning disable IDE0010 | ||
namespace Sales; | ||
|
||
using Microsoft.Extensions.Hosting; | ||
using MassTransit; | ||
using Microsoft.Extensions.DependencyInjection; | ||
using System.Security.Cryptography; | ||
using System.Text; | ||
using System.Reflection; | ||
|
||
class Program | ||
{ | ||
public static IHostBuilder CreateHostBuilder(string[] args) | ||
{ | ||
var host = Host.CreateDefaultBuilder(args) | ||
.ConfigureServices((hostContext, services) => | ||
{ | ||
services.AddMassTransit(x => | ||
{ | ||
x.UsingRabbitMq((context, cfg) => | ||
{ | ||
cfg.Host("localhost", "/", h => | ||
{ | ||
h.Username("guest"); | ||
h.Password("guest"); | ||
}); | ||
|
||
cfg.ConfigureEndpoints(context); | ||
}); | ||
|
||
x.AddConsumers(Assembly.GetExecutingAssembly()); | ||
|
||
x.AddConfigureEndpointsCallback((name, cfg) => | ||
{ | ||
if (cfg is IRabbitMqReceiveEndpointConfigurator rmq) | ||
{ | ||
rmq.SetQuorumQueue(); | ||
} | ||
}); | ||
}); | ||
|
||
services.AddSingleton<SimulationEffects>(); | ||
}); | ||
|
||
return host; | ||
} | ||
|
||
static async Task Main(string[] args) | ||
{ | ||
Console.SetWindowSize(65, 15); | ||
Console.Title = "Processing (Sales)"; | ||
|
||
var host = CreateHostBuilder(args).Build(); | ||
await host.StartAsync(); | ||
|
||
var state = host.Services.GetRequiredService<SimulationEffects>(); | ||
await RunUserInterfaceLoop(state); | ||
} | ||
|
||
static Task RunUserInterfaceLoop(SimulationEffects state) | ||
{ | ||
while (true) | ||
{ | ||
Console.Clear(); | ||
Console.WriteLine($"Sales Endpoint"); | ||
Console.WriteLine("Press F to process messages faster"); | ||
Console.WriteLine("Press S to process messages slower"); | ||
|
||
Console.WriteLine("Press ESC to quit"); | ||
Console.WriteLine(); | ||
|
||
state.WriteState(Console.Out); | ||
|
||
var input = Console.ReadKey(true); | ||
|
||
switch (input.Key) | ||
{ | ||
case ConsoleKey.F: | ||
state.ProcessMessagesFaster(); | ||
break; | ||
case ConsoleKey.S: | ||
state.ProcessMessagesSlower(); | ||
break; | ||
case ConsoleKey.Escape: | ||
return Task.CompletedTask; | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
<Project Sdk="Microsoft.NET.Sdk"> | ||
|
||
<PropertyGroup> | ||
<TargetFramework>net8.0</TargetFramework> | ||
<OutputType>Exe</OutputType> | ||
<ImplicitUsings>enable</ImplicitUsings> | ||
<Nullable>enable</Nullable> | ||
<OutputPath>..\binaries\Sales\</OutputPath> | ||
<ApplicationIcon>processing-time-alternate.ico</ApplicationIcon> | ||
</PropertyGroup> | ||
|
||
<ItemGroup> | ||
<PackageReference Include="MassTransit.RabbitMQ" Version="8.2.3" /> | ||
<PackageReference Include="Microsoft.Extensions.Hosting" Version="8.0.0" /> | ||
</ItemGroup> | ||
|
||
<ItemGroup> | ||
<ProjectReference Include="..\Messages\Messages.csproj" /> | ||
</ItemGroup> | ||
</Project> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
namespace Sales; | ||
|
||
public class SimulationEffects | ||
{ | ||
public void WriteState(TextWriter output) | ||
{ | ||
output.WriteLine("Base time to handle each order: {0} seconds", baseProcessingTime.TotalSeconds); | ||
} | ||
|
||
public Task SimulateMessageProcessing(CancellationToken cancellationToken = default) | ||
{ | ||
return Task.Delay(baseProcessingTime, cancellationToken); | ||
} | ||
|
||
public void ProcessMessagesFaster() | ||
{ | ||
if (baseProcessingTime > TimeSpan.Zero) | ||
{ | ||
baseProcessingTime -= increment; | ||
} | ||
} | ||
|
||
public void ProcessMessagesSlower() | ||
{ | ||
baseProcessingTime += increment; | ||
} | ||
|
||
TimeSpan baseProcessingTime = TimeSpan.FromMilliseconds(1300); | ||
TimeSpan increment = TimeSpan.FromMilliseconds(100); | ||
} |
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
[*.cs] | ||
|
||
# Justification: Test project | ||
dotnet_diagnostic.CA2007.severity = none | ||
|
||
# Justification: Tests don't support cancellation and don't need to forward IMessageHandlerContext.CancellationToken | ||
dotnet_diagnostic.NSB0002.severity = suggestion |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
namespace Shipping; | ||
|
||
using System.Threading.Tasks; | ||
using MassTransit; | ||
using Messages; | ||
|
||
public class OrderBilledHandler(SimulationEffects simulationEffects) : IConsumer<OrderBilled> | ||
{ | ||
public Task Consume(ConsumeContext<OrderBilled> context) | ||
{ | ||
return simulationEffects.SimulateOrderBilledMessageProcessing(context.CancellationToken); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
namespace Shipping; | ||
|
||
using System.Threading.Tasks; | ||
using MassTransit; | ||
using Messages; | ||
|
||
public class OrderPlacedHandler(SimulationEffects simulationEffects) : IConsumer<OrderPlaced> | ||
{ | ||
public Task Consume(ConsumeContext<OrderPlaced> context) | ||
{ | ||
return simulationEffects.SimulateOrderPlacedMessageProcessing(context.CancellationToken); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
#pragma warning disable IDE0010 | ||
namespace Shipping; | ||
|
||
using Microsoft.Extensions.Hosting; | ||
using MassTransit; | ||
using Microsoft.Extensions.DependencyInjection; | ||
using System.Security.Cryptography; | ||
using System.Text; | ||
using System.Reflection; | ||
|
||
class Program | ||
{ | ||
public static IHostBuilder CreateHostBuilder(string[] args) | ||
{ | ||
var host = Host.CreateDefaultBuilder(args) | ||
.ConfigureServices((_, services) => | ||
{ | ||
services.AddMassTransit(x => | ||
{ | ||
x.UsingRabbitMq((context, cfg) => | ||
{ | ||
cfg.Host("localhost", "/", h => | ||
{ | ||
h.Username("guest"); | ||
h.Password("guest"); | ||
}); | ||
|
||
cfg.ConfigureEndpoints(context); | ||
}); | ||
|
||
x.AddConsumers(Assembly.GetExecutingAssembly()); | ||
|
||
x.AddConfigureEndpointsCallback((name, cfg) => | ||
{ | ||
if (cfg is IRabbitMqReceiveEndpointConfigurator rmq) | ||
{ | ||
rmq.SetQuorumQueue(); | ||
} | ||
}); | ||
}); | ||
|
||
services.AddSingleton<SimulationEffects>(); | ||
}); | ||
|
||
return host; | ||
} | ||
|
||
static async Task Main(string[] args) | ||
{ | ||
Console.SetWindowSize(65, 15); | ||
|
||
Console.Title = "Processing (Shipping)"; | ||
|
||
var host = CreateHostBuilder(args).Build(); | ||
await host.StartAsync(); | ||
|
||
var state = host.Services.GetRequiredService<SimulationEffects>(); | ||
await RunUserInterfaceLoop(state); | ||
} | ||
|
||
static Task RunUserInterfaceLoop(SimulationEffects state) | ||
{ | ||
while (true) | ||
{ | ||
Console.Clear(); | ||
Console.WriteLine("Shipping Endpoint"); | ||
Console.WriteLine("Press D to toggle resource degradation simulation"); | ||
Console.WriteLine("Press F to process OrderBilled events faster"); | ||
Console.WriteLine("Press S to process OrderBilled events slower"); | ||
Console.WriteLine("Press ESC to quit"); | ||
Console.WriteLine(); | ||
|
||
state.WriteState(Console.Out); | ||
|
||
var input = Console.ReadKey(true); | ||
|
||
switch (input.Key) | ||
{ | ||
case ConsoleKey.D: | ||
state.ToggleDegradationSimulation(); | ||
break; | ||
case ConsoleKey.F: | ||
state.ProcessMessagesFaster(); | ||
break; | ||
case ConsoleKey.S: | ||
state.ProcessMessagesSlower(); | ||
break; | ||
case ConsoleKey.Escape: | ||
return Task.CompletedTask; | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
<Project Sdk="Microsoft.NET.Sdk"> | ||
|
||
<PropertyGroup> | ||
<TargetFramework>net8.0</TargetFramework> | ||
<OutputType>Exe</OutputType> | ||
<ImplicitUsings>enable</ImplicitUsings> | ||
<Nullable>enable</Nullable> | ||
<OutputPath>..\binaries\Shipping\</OutputPath> | ||
<ApplicationIcon>processing-time.ico</ApplicationIcon> | ||
</PropertyGroup> | ||
|
||
<ItemGroup> | ||
<ProjectReference Include="..\Messages\Messages.csproj" /> | ||
</ItemGroup> | ||
|
||
<ItemGroup> | ||
<PackageReference Include="MassTransit.RabbitMQ" Version="8.2.3" /> | ||
<PackageReference Include="Microsoft.Extensions.Hosting" Version="8.0.0" /> | ||
</ItemGroup> | ||
|
||
</Project> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
namespace Shipping; | ||
|
||
public class SimulationEffects | ||
{ | ||
public void WriteState(TextWriter output) | ||
{ | ||
output.WriteLine("Base time to handle each OrderBilled event: {0} seconds", baseProcessingTime.TotalSeconds); | ||
|
||
output.Write("Simulated degrading resource: "); | ||
output.WriteLine(degradingResourceSimulationStarted.HasValue ? "ON" : "OFF"); | ||
} | ||
|
||
public Task SimulateOrderBilledMessageProcessing(CancellationToken cancellationToken = default) | ||
{ | ||
return Task.Delay(baseProcessingTime, cancellationToken); | ||
} | ||
|
||
public void ProcessMessagesFaster() | ||
{ | ||
if (baseProcessingTime > TimeSpan.Zero) | ||
{ | ||
baseProcessingTime -= increment; | ||
} | ||
} | ||
|
||
public void ProcessMessagesSlower() | ||
{ | ||
baseProcessingTime += increment; | ||
} | ||
|
||
public Task SimulateOrderPlacedMessageProcessing(CancellationToken cancellationToken = default) | ||
{ | ||
var delay = TimeSpan.FromMilliseconds(200) + Degradation(); | ||
return Task.Delay(delay, cancellationToken); | ||
} | ||
|
||
public void ToggleDegradationSimulation() | ||
{ | ||
degradingResourceSimulationStarted = degradingResourceSimulationStarted.HasValue ? default(DateTime?) : DateTime.UtcNow; | ||
} | ||
|
||
TimeSpan Degradation() | ||
{ | ||
var timeSinceDegradationStarted = DateTime.UtcNow - (degradingResourceSimulationStarted ?? DateTime.MaxValue); | ||
if (timeSinceDegradationStarted < TimeSpan.Zero) | ||
{ | ||
return TimeSpan.Zero; | ||
} | ||
|
||
return new TimeSpan(timeSinceDegradationStarted.Ticks / degradationRate); | ||
} | ||
|
||
TimeSpan baseProcessingTime = TimeSpan.FromMilliseconds(700); | ||
TimeSpan increment = TimeSpan.FromMilliseconds(100); | ||
|
||
DateTime? degradingResourceSimulationStarted; | ||
const int degradationRate = 5; | ||
} |
Binary file not shown.