ICurrentPrincipalProvider
Tells the mediator who the current caller is, as a stable id. Its only use in Trax is bucketing the per-principal concurrency limit on direct runs. It is not used for authorization: nothing here grants or checks access.
Signature
namespace Trax.Mediator.Services.Principal;
public interface ICurrentPrincipalProvider
{
string? GetCurrentPrincipalId();
}Returns: the current principal's stable id, or null when there is none (the scheduler, a remote worker, an anonymous request). A run with a null or empty id is not limited per principal; the per-train and global limits still apply. Ids are compared ordinally.
Registrations
| Registered by | Implementation |
|---|---|
AddMediator | A default that always returns null, so PerPrincipalMaxConcurrentRun limits nothing on its own |
AddTraxApi (called by AddTraxGraphQL) | Reads the trax:principal-id claim of the current request's authenticated user. Call it after AddTrax, or the mediator's default wins. |
A host outside ASP.NET Core that wants the per-principal limit registers its own as a singleton after AddMediator.
Writing one
- Singleton, thread-safe. The concurrency limiter is a singleton and resolves the provider once. Read ambient state (the current request, an
AsyncLocal) on each call rather than capturing it. - Cheap. It is called on every direct run while the per-principal limit is set.
- An id the caller cannot choose. Use something authenticated, such as the subject claim. An id taken from a header or other client input lets a caller spread its runs across many buckets and escape the limit, because a new id starts with a full budget. Never return a per-request or random value.
Example
using Trax.Mediator.Services.Principal;
public sealed class JobContextPrincipalProvider : ICurrentPrincipalProvider
{
public string? GetCurrentPrincipalId() => JobContext.Current?.TenantId;
}
services.AddTrax(trax => trax
.AddEffects(effects => effects.UsePostgres(connectionString))
.AddMediator(mediator => mediator
.ScanAssemblies(typeof(Program).Assembly)
.PerPrincipalMaxConcurrentRun(5)));
services.AddSingleton<ICurrentPrincipalProvider, JobContextPrincipalProvider>();Package
dotnet add package Trax.Mediator