18.4 The worker
Shopfront.Worker/Program.cs:
using Shopfront;
using Shopfront.Extensions;
using Shopfront.Staff;
using Trax.Api.Auth;
using Trax.Effect.Broadcaster.RabbitMQ.Extensions;
using Trax.Effect.Data.Extensions;
using Trax.Effect.Data.Postgres.Extensions;
using Trax.Effect.Extensions;
using Trax.Effect.JunctionProvider.Logging.Extensions;
using Trax.Effect.JunctionProvider.Progress.Extensions;
using Trax.Effect.Provider.Parameter.Extensions;
using Trax.Mediator.Extensions;
using Trax.Scheduler.Extensions;
var builder = WebApplication.CreateBuilder(args);
var connectionString =
builder.Configuration.GetConnectionString("Shopfront")
?? throw new InvalidOperationException("ConnectionStrings:Shopfront is not set.");
var rabbitMq =
builder.Configuration.GetConnectionString("RabbitMq")
?? throw new InvalidOperationException("ConnectionStrings:RabbitMq is not set.");
builder.Services.AddShopfront(connectionString);
// The trains ask who the caller is. On the worker nobody is, and that is the answer they get.
builder.Services.AddTraxPrincipalAccessor();
builder.Services.AddTrax(trax =>
trax.AddEffects(effects =>
effects
.UsePostgres(connectionString)
// The runs this worker executes reach the hub's subscriptions over RabbitMQ.
.UseBroadcaster(broadcaster => broadcaster.UseRabbitMq(rabbitMq))
.SaveTrainParameters()
.AddJunctionLogger(serializeJunctionData: true)
.AddJunctionProgress()
.AddDecisionRecording()
.AddJunctionEvents()
.AddLifecycleHook<StaffFailureHook>()
)
.AddMediator(mediator =>
mediator
.ScanAssemblies(typeof(ManifestNames).Assembly)
// The hub authorized every job this worker runs before it was queued.
.AllowMissingAuthorizationService()
)
);
builder.Services.AddTraxWorker(worker => worker.WorkerCount = 2);
// The process is up. Trax has no check of its own for a worker.
builder.Services.AddHealthChecks();
var app = builder.Build();
app.MapHealthChecks("/health/live");
await app.RunAsync();The worker publishes the events of every run it executes. Trax has no health check for a worker,
so /health/live says only that the process answers. A worker that is stopped finishes the run it
is in, for up to 30 seconds, then gives up on it; a worker that dies leaves its run for the hub to
fail, as chapter 11 showed.
Shopfront.Worker/Shopfront.Worker.csproj:
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>net10.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<RootNamespace>Shopfront</RootNamespace>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\Shopfront.Core\Shopfront.Core.csproj" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Trax.Effect.Broadcaster.RabbitMQ" />
<PackageReference Include="Trax.Effect.JunctionProvider.Logging" />
<PackageReference Include="Trax.Effect.JunctionProvider.Progress" />
<PackageReference Include="Trax.Effect.Provider.Parameter" />
<PackageReference Include="Trax.Scheduler" />
</ItemGroup>
</Project>Shopfront.Worker/appsettings.json:
{
"ConnectionStrings": {
"Shopfront": "Host=localhost;Database=shopfront;Username=postgres;Password=shopfront",
"RabbitMq": "amqp://guest:guest@localhost:5672"
},
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
}
}SDK Reference
Deployment topologies | Move a domain data context to EF migrations | UseRabbitMq | AddTraxHealthCheck | Health and liveness | Startup refusals | UseTraxApiDashboard