Core Configuration
This page explains how to configure the AsyncEndpoints library using the comprehensive configuration system that allows fine-tuning of all aspects of the async processing pipeline.
Overview
The AsyncEndpoints configuration system is built around the AsyncEndpointsConfigurations class, which provides access to three main configuration sections:
- Worker Configurations: Settings for background job processing
- Job Manager Configurations: Settings for job lifecycle management
- Response Configurations: Settings for HTTP response customization
Basic Configuration Setup
Using Default Configuration
The simplest way to configure AsyncEndpoints is to use the default settings:
using AsyncEndpoints;
var builder = WebApplication.CreateBuilder(args);
builder.Services
.AddAsyncEndpoints() // Uses default configuration
.AddAsyncEndpointsInMemoryStore()
.AddAsyncEndpointsWorker();
var app = builder.Build();
Custom Configuration with Fluent API
You can customize all configuration aspects using the fluent API:
builder.Services.AddAsyncEndpoints(options =>
{
// Configure worker settings
options.WorkerConfigurations.MaximumConcurrency = Environment.ProcessorCount;
options.WorkerConfigurations.PollingIntervalMs = 1000;
options.WorkerConfigurations.JobTimeoutMinutes = 30;
// Configure job manager settings
options.JobManagerConfiguration.DefaultMaxRetries = 3;
options.JobManagerConfiguration.RetryDelayBaseSeconds = 2.0;
// Configure response customization
options.ResponseConfigurations.JobSubmittedResponseFactory = async (job, context) =>
{
context.Response.Headers.Append("Async-Job-Id", job.Id.ToString());
return Results.Accepted($"/jobs/{job.Id}", job);
};
});
Configuration Classes Hierarchy
AsyncEndpointsConfigurations
This is the main configuration class that contains all sub-configurations:
public sealed class AsyncEndpointsConfigurations
{
public AsyncEndpointsWorkerConfigurations WorkerConfigurations { get; set; } = new();
public AsyncEndpointsJobManagerConfiguration JobManagerConfiguration { get; set; } = new();
public AsyncEndpointsResponseConfigurations ResponseConfigurations { get; set; } = new();
}
AsyncEndpointsWorkerConfigurations
Configuration for background worker services:
public sealed class AsyncEndpointsWorkerConfigurations
{
public Guid WorkerId { get; set; } = Guid.NewGuid();
public int MaximumConcurrency { get; set; } = Environment.ProcessorCount;
public int PollingIntervalMs { get; set; } = AsyncEndpointsConstants.DefaultPollingIntervalMs; // 1000 ms
public int JobTimeoutMinutes { get; set; } = AsyncEndpointsConstants.DefaultJobTimeoutMinutes; // 30 minutes
public int BatchSize { get; set; } = AsyncEndpointsConstants.DefaultBatchSize; // 5
public int MaximumQueueSize { get; set; } = AsyncEndpointsConstants.DefaultMaximumQueueSize; // 50
}
AsyncEndpointsJobManagerConfiguration
Configuration for job management and retry logic:
public sealed class AsyncEndpointsJobManagerConfiguration
{
public int DefaultMaxRetries { get; set; } = AsyncEndpointsConstants.MaximumRetries; // 3
public double RetryDelayBaseSeconds { get; set; } = 2.0;
public TimeSpan JobClaimTimeout { get; set; } = TimeSpan.FromMinutes(5);
public int MaxConcurrentJobs { get; set; } = 10;
public int JobPollingIntervalMs { get; set; } = 1000;
public int MaxClaimBatchSize { get; set; } = 10;
public TimeSpan StaleJobClaimCheckInterval { get; set; } = TimeSpan.FromMinutes(1);
}
AsyncEndpointsResponseConfigurations
Configuration for response customization:
public sealed class AsyncEndpointsResponseConfigurations
{
public Func<Job, HttpContext, Task<IResult>> JobSubmittedResponseFactory { get; set; } = ResponseDefaults.CreateJobSubmittedResponse;
public Func<MethodResult<Job>, HttpContext, Task<IResult>> JobStatusResponseFactory { get; set; } = ResponseDefaults.CreateJobStatusResponse;
public Func<AsyncEndpointError?, HttpContext, Task<IResult>> JobSubmissionErrorResponseFactory { get; set; } = ResponseDefaults.CreateJobSubmissionErrorResponse;
public Func<Exception, HttpContext, Task<IResult>> ExceptionResponseFactory { get; set; } = ResponseDefaults.CreateExceptionResponse;
}
Configuration Validation
The library does not include built-in validation for configuration values. The configuration system accepts all values as provided, so it's important to validate configuration values manually during setup:
// Example validation approach
public void ValidateConfiguration(AsyncEndpointsConfigurations config)
{
if (config.WorkerConfigurations.MaximumConcurrency <= 0)
throw new ArgumentException("MaximumConcurrency must be greater than 0");
if (config.WorkerConfigurations.MaximumQueueSize <= 0)
throw new ArgumentException("MaximumQueueSize must be greater than 0");
if (config.JobManagerConfiguration.DefaultMaxRetries < 0)
throw new ArgumentException("DefaultMaxRetries cannot be negative");
if (config.WorkerConfigurations.JobTimeoutMinutes <= 0)
throw new ArgumentException("JobTimeoutMinutes must be greater than 0");
}
// Call validation after configuration
builder.Services.AddAsyncEndpoints(options =>
{
// Configure options
options.WorkerConfigurations.MaximumConcurrency = Environment.ProcessorCount;
// ... other configuration
// Validate the configuration
ValidateConfiguration(options);
});
Common Configuration Patterns
Development Configuration
builder.Services.AddAsyncEndpoints(options =>
{
// More verbose settings for development
options.WorkerConfigurations.MaximumConcurrency = 2; // Lower concurrency for debugging
options.WorkerConfigurations.PollingIntervalMs = 1000; // Faster polling
options.WorkerConfigurations.JobTimeoutMinutes = 10; // Shorter timeouts
options.WorkerConfigurations.MaximumQueueSize = 10; // Smaller queue for testing
options.JobManagerConfiguration.DefaultMaxRetries = 1; // Fewer retries in development
options.JobManagerConfiguration.RetryDelayBaseSeconds = 1.0; // Faster retries
});
Production Configuration
builder.Services.AddAsyncEndpoints(options =>
{
// Optimized settings for production
options.WorkerConfigurations.MaximumConcurrency = Math.Min(Environment.ProcessorCount, 16);
options.WorkerConfigurations.PollingIntervalMs = 3000; // Balance between responsiveness and resource usage (default is 1000ms)
options.WorkerConfigurations.JobTimeoutMinutes = 60; // Longer timeouts for complex operations
options.WorkerConfigurations.MaximumQueueSize = 1000; // Larger queue for high throughput
options.JobManagerConfiguration.DefaultMaxRetries = 5; // More retries for reliability
options.JobManagerConfiguration.RetryDelayBaseSeconds = 2.0; // Standard exponential backoff
// Custom response factory for monitoring
options.ResponseConfigurations.JobSubmittedResponseFactory = async (job, context) =>
{
// Add custom headers for monitoring
context.Response.Headers.Append("X-Async-Job-Id", job.Id.ToString());
context.Response.Headers.Append("X-Async-Job-Name", job.Name);
return Results.Accepted($"/jobs/{job.Id}", job);
};
});
Environment-Based Configuration
You can configure different settings based on the hosting environment:
builder.Services.AddAsyncEndpoints(options =>
{
if (builder.Environment.IsDevelopment())
{
options.WorkerConfigurations.MaximumConcurrency = 2;
options.WorkerConfigurations.MaximumQueueSize = 10;
options.JobManagerConfiguration.DefaultMaxRetries = 1;
}
else if (builder.Environment.IsProduction())
{
options.WorkerConfigurations.MaximumConcurrency = Environment.ProcessorCount;
options.WorkerConfigurations.MaximumQueueSize = 500;
options.JobManagerConfiguration.DefaultMaxRetries = 3;
}
// Common settings for all environments
options.WorkerConfigurations.PollingIntervalMs = 2000;
});
Configuration Best Practices
Use Appropriate Concurrency Levels
- Start with
Environment.ProcessorCountfor CPU-bound operations - Adjust based on I/O patterns (may be higher for I/O-bound operations)
- Monitor system performance to optimize
Set Realistic Timeouts
- Job timeouts should be based on expected processing times
- Consider external dependencies when setting timeouts
- Account for retry delays in overall timeout calculations
Configure Queue Size Appropriately
- Queue size limits provide circuit breaker functionality
- Balance between throughput and memory usage
- Consider the number of concurrent workers when setting limits
Validate Configuration Changes
- Test configuration changes in a staging environment
- Monitor performance metrics after changes
- Have rollback plans for configuration changes
The core configuration system provides the flexibility to optimize AsyncEndpoints for your specific use cases while maintaining system reliability and performance.