Workers¶
Target Architecture — Final-State Design
This page describes the final-state background workers of the Marketplace Platform. Workers are MassTransit consumers hosted from ConnectSoft.Template.Worker-derived projects, triggered by commands and events on Azure Service Bus, and deployed as independently scaled units.
The Marketplace runs five background workers that handle the asynchronous, long-running, and event-driven work behind publishing, installation, indexing, and quality assurance. Each worker is an idempotent consumer that deduplicates on eventId, asserts tenantId, and emits canonical events on completion.
Worker catalog¶
| Worker | Trigger | Purpose | Input | Output | Retry | Idempotency |
|---|---|---|---|---|---|---|
| MarketplacePublishingWorker | PublishAsset / ReleaseAssetVersion command |
Drives the publishing saga: stages the package, invokes quality scan, applies the policy gate, signs, and releases. | Publish command + staged package ref | AssetPublished, AssetVersionReleased; updated AssetVersion |
Exponential backoff, 5 attempts; saga compensation on terminal failure | Keyed on (assetId, version); re-running a released version is a no-op |
| AssetQualityScanWorker | ScanAssetQuality command (from publishing saga) |
Runs static, structural, security, and policy quality checks on a submitted asset package. | Staged package blob ref | AssetQualityScanned (verdict + findings) |
3 attempts; transient scanner errors retried, content failures terminal | Keyed on package content hash; identical content reuses prior verdict |
| AssetIndexingWorker | AssetPublished / AssetVersionReleased / AssetReviewed events |
Builds and updates the search index documents and catalog read models for discovery and ranking. | Catalog/version/review events | Updated search index; AssetIndexed |
At-least-once with 5 attempts; idempotent upsert | Keyed on (assetId, version, indexDocVersion); upserts are naturally idempotent |
| CompatibilityEvaluationWorker | EvaluateCompatibility command / AssetVersionReleased event |
Computes compatibility verdicts asynchronously (full-matrix and on-demand), caching results. | Asset version + target descriptor | CompatibilityEvaluated; cached AssetCompatibility verdict |
3 attempts; cache-miss recompute on failure | Keyed on (assetId, version, targetHash); cached verdict short-circuits re-evaluation |
| InstallationWorker | InstallAsset command / CompatibilityEvaluated + LicenseGranted + DependenciesResolved events |
Drives the installation saga: resolve dependencies, verify compatibility and license, apply the asset, and record provenance with rollback. | Install command + resolved graph | AssetInstalled or AssetInstallationFailed; updated AssetInstallation |
Exponential backoff, 5 attempts; compensating rollback on terminal failure | Keyed on installationId; partially applied installs resume or roll back deterministically |
Event-flow diagram¶
flowchart TB
PublishCmd["PublishAsset / ReleaseAssetVersion"] --> MPW["MarketplacePublishingWorker"]
MPW -->|"ScanAssetQuality"| AQW["AssetQualityScanWorker"]
AQW -->|"AssetQualityScanned"| MPW
MPW -->|"AssetPublished / AssetVersionReleased"| Bus["Azure Service Bus"]
Bus -->|"AssetPublished / AssetVersionReleased"| AIW["AssetIndexingWorker"]
Bus -->|"AssetVersionReleased"| CEW["CompatibilityEvaluationWorker"]
Bus -->|"AssetReviewed"| AIW
InstallCmd["InstallAsset"] --> IW["InstallationWorker"]
IW -->|"EvaluateCompatibility"| CEW
CEW -->|"CompatibilityEvaluated"| IW
IW -->|"resolve dependencies"| DRS["DependencyResolutionService"]
DRS -->|"DependenciesResolved"| IW
IW -->|"check entitlement"| LS["LicenseService"]
LS -->|"LicenseGranted"| IW
IW -->|"AssetInstalled"| Bus
AIW -->|"AssetIndexed"| Bus
Hold "Alt" / "Option" to enable pan & zoom
Worker semantics¶
- Hosting — each worker is a separate deployable derived from
ConnectSoft.Template.Worker, scaled by queue depth (KEDA on Azure Service Bus). See Deployment. - Saga coordination —
MarketplacePublishingWorkerandInstallationWorkerhost MassTransit state-machine sagas that persist saga state and emit compensating actions on failure. - Idempotency — all workers deduplicate on
eventIdand a handler-specific idempotency key (see Event Envelope); reprocessing never produces duplicate releases or installs. - Poison handling — unprocessable messages move to a dead-letter subqueue with the full envelope preserved for replay and investigation by the Observability tooling.
- Tenant guard — every handler asserts the message
tenantIdagainst the operation scope before touching any store. - Tracing —
traceIdandcorrelationIdpropagate into OpenTelemetry spans and Serilog context so a publish or install can be followed end to end.
Continue to Events, Workflows, and Observability.