Configuration
Requirements: Dapr 1.18+ with mTLS enabled. .NET 10.0 SDK.
WorkManager supports configuration via environment variables and command-line arguments.
Precedence
Configuration is loaded in the following order:
- Environment variables (loaded first)
- Command-line arguments (loaded second)
Command-line arguments take precedence over environment variables.
Configuration Keys
Port Configuration
| Key | Description | Default |
|---|---|---|
HttpPort |
HTTP port (REST, Swagger, health) | 5001 |
GrpcPort |
gRPC port (native gRPC HTTP/2 h2c) | 5002 |
DaprHttpPort |
Dapr HTTP port | 3500 |
DaprGrpcPort |
Dapr gRPC port | 50001 |
Logging
| Key | Description | Default |
|---|---|---|
Logging:LogLevel:Default |
Minimum log level | Information |
Valid log levels: Trace, Debug, Information, Warning, Error, Critical, None
Dapr Configuration
| Key | Description | Default |
|---|---|---|
pubsubName |
Pub/sub component name | pubsub |
stateStoreName |
State store component name | statestore |
Group Lock Tuning
When multiple workers share a group, the WorkManager acquires a
distributed lock via the Dapr state store before publishing the
worker's response. Lock contention is handled via Dapr redelivery
(see Worker Lifecycle for the
contract). These env vars tune the acquire loop; they do not
gate the number of Dapr redeliveries — that is controlled by the
Dapr pubsub component's maxRetries metadata.
| Key | Description | Default | Range |
|---|---|---|---|
GROUP_LOCK_MAX_RETRIES |
Max acquire attempts before throwing LockContentionException. The thrown exception causes the message to be nacked (TopicResponseAction.Retry), which makes Dapr redeliver it after backoff. |
3 |
1–20 |
GROUP_LOCK_RETRY_BASE_DELAY_MS |
Base delay between acquire attempts. Actual delay is RetryBaseDelayMs * 2^attempt. |
500 |
10–60000 |
Worker Recovery
The WorkManagerRecoveryHostedService runs on startup and restores
all persisted worker assignments. Multiple WorkManager instances
elect a single leader via a Dapr state-store lease so concurrent
recovery doesn't waste memory (see
Worker Lifecycle: Multi-instance safety).
| Key | Description | Default | Range |
|---|---|---|---|
WORKER_RECOVERY_ON_START |
Whether to run recovery automatically on startup. When false, the health check reports Healthy and workers must be restored manually via the RecoverWorkers gRPC endpoint. |
true |
true/false/1/0/yes/no/on/off |
WORKER_RECOVERY_LEASE_TTL_SECONDS |
How long the recovery leader lease is held before another instance may take over. Also the upper bound on how long a crashed leader blocks others. | 300 |
10–86400 |
WORKER_RECOVERY_ACQUIRE_TIMEOUT_SECONDS |
How long this instance will wait to acquire the lease before skipping recovery. | 30 |
1–600 |
Dapr Resiliency
The DaprResiliencePipeline wraps every Dapr SDK call the WorkManager
makes (pub/sub publish, state store read/write, recovery lease
acquisition) in a Polly pipeline: retry with exponential backoff,
then circuit breaker. The circuit state is exposed at
/health (tag dapr); when the circuit opens, the health check
reports Unhealthy and messages on dependent topics will be
nacked (Retry) rather than silently dropped.
| Key | Description | Default | Range |
|---|---|---|---|
DAPR_RETRY_ATTEMPTS |
Max retry attempts per Dapr call before the pipeline throws. | 3 |
0–20 |
DAPR_RETRY_BASE_DELAY_MS |
Base delay between attempts; actual delay is RetryBaseDelayMs * 2^attempt. |
200 |
10–60000 |
DAPR_CIRCUIT_BREAKER_THRESHOLD |
Minimum throughput before the circuit can trip (Polly MinimumThroughput). |
5 |
1–1000 |
DAPR_CIRCUIT_BREAKER_DURATION_SECONDS |
How long the circuit stays open before transitioning to half-open. | 30 |
1–3600 |
The circuit breaker uses Polly's FailureRatio = 0.5 (a 50% failure
rate trips the circuit). The above env vars control the other knobs.
Environment Variables
Set configuration using environment variables:
export HttpPort=8080
export GrpcPort=5002
export DaprHttpPort=3500
export DaprGrpcPort=50001
export Logging:LogLevel:Default=Debug
export pubsubName=my-pubsub
export stateStoreName=my-state
export GROUP_LOCK_MAX_RETRIES=5
export GROUP_LOCK_RETRY_BASE_DELAY_MS=250
export WORKER_RECOVERY_ON_START=true
export WORKER_RECOVERY_LEASE_TTL_SECONDS=300
export WORKER_RECOVERY_ACQUIRE_TIMEOUT_SECONDS=30
export DAPR_RETRY_ATTEMPTS=3
export DAPR_RETRY_BASE_DELAY_MS=200
export DAPR_CIRCUIT_BREAKER_THRESHOLD=5
export DAPR_CIRCUIT_BREAKER_DURATION_SECONDS=30
Command-Line Arguments
Pass arguments when running the application:
Virtufin.WorkManager --http-port 8080 --grpc-port 5002
Available Arguments
| Argument | Description | Default |
|---|---|---|
--http-port <port> |
HTTP port (REST, Swagger, health) | 5001 |
--grpc-port <port> |
gRPC port (native gRPC HTTP/2 h2c) | 5002 |
--dapr-http-port <port> |
Dapr HTTP port | 3500 |
--dapr-grpc-port <port> |
Dapr gRPC port | 50001 |
Examples
Using Environment Variables
export HttpPort=3000
export GrpcPort=3002
./Virtufin.WorkManager
Using Command-Line Arguments
./Virtufin.WorkManager --http-port 3000 --grpc-port 3002
Combining Both
Environment variables set defaults, command-line arguments override:
export HttpPort=3000
./Virtufin.WorkManager --grpc-port 3002
In this example, HttpPort is 3000 (from environment) and GrpcPort is 3002 (from command line).