Asset Publishing and Outbox
Summary
Asset events are staged in a transactional outbox on save and drained by a registered background relay through the shared outbox processor and event bus.
Audience
Engineering, integration, QA, architecture, and security reviewers.
Reference Content
Outbox row (OutboxMessage)
| Field | Purpose |
|---|---|
Id | Row identity (GUID) |
EventId | Integration-event identity (GUID) |
EventType | Contract type name (for example AssetAssigned) |
PayloadJson | Serialized contract (classified; not exposed here) |
OccurredAtUtc | Event time |
ProcessedOnUtc | Set when published |
Status | Pending, Processing, Processed, or Failed |
RetryCount | Incremented on each failed publish |
ErrorMessage | Last publish error text |
CorrelationId | Correlation for tracing |
TenantId | GUID tenant (nullable for asset events) |
SourceService | asset-service |
Staging (in the write transaction)
AssetDbContext.SaveChangesAsync calls DispatchDomainEventsToOutbox before base.SaveChangesAsync. For each tracked aggregate with pending domain events, every event is mapped to a contract, the completeness guard runs, and the serialized row is added to OutboxMessages. The aggregate's domain events are then cleared. The outbox rows commit atomically with the aggregate, audit, and timeline changes in one local transaction.
Relay (after commit)
OutboxRelayHostedService is a registered hosted service. Every 10 seconds it opens a scope, resolves IOutboxProcessor, and calls ProcessPendingAsync(50, ...). AssetOutboxMessageStore.GetPendingAsync returns rows whose Status is Pending or Failed, ordered by OccurredAtUtc, capped at the batch size.
For each row the processor calls RabbitMqEventBus.PublishAsync:
- On success,
MarkProcessedAsyncsetsStatus = Processed, stampsProcessedOnUtc, and clears the error. - On a
falseresult or an exception,MarkFailedAsyncsetsStatus = Failed, incrementsRetryCount, and records the error. The row is retried on the next pass.
Diagnostics
Outbox rows are readable through the asset outbox diagnostics endpoint (documented in the API section), which projects row metadata for inspection. This is a read path only.
Verified boundaries
- A publish failure never blocks the request that wrote the row; the row simply remains eligible for a later pass.
- Broker delivery depends on broker availability and configuration and is not verified here.
- There is no verified retry ceiling, dead-letter path, or outbox cleanup. See Retry and failure and Event limitations.
Source References
microservices/src/asset-service/Infrastructure/AssetDbContext.csmicroservices/src/asset-service/Messaging/OutboxRelayHostedService.csmicroservices/src/shared-kernel/Messaging/OutboxProcessor.csmicroservices/src/shared-kernel/Outbox/OutboxMessage.csmicroservices/src/asset-service/Infrastructure/Persistence.cs
Related Articles
See Also
Keywords
- Transactional outbox
- Hosted relay
- Outbox processor
Revision Information
- Status: Draft
- Last reviewed: 2026-07-17
- Review cycle: Quarterly