Configuration Analyzers
Configuration Analyzers
Configuration analyzers detect issues with pipeline configuration that can lead to performance problems, resource leaks, or silent failures. These analyzers focus on ensuring that your pipeline configuration is optimal for your workload and doesn't introduce hidden problems.
NP9501: Unbounded Materialization Configuration
ID: NP9501
Severity: Error
Category: Configuration
This analyzer detects when PipelineRetryOptions.MaxMaterializedItems is null or missing, which causes unbounded memory growth in ResilientExecutionStrategy and silently disables restart functionality. This is a critical configuration error that can lead to OutOfMemoryException in production.
Why This Matters
Unbounded materialization configuration causes:
- Memory Leaks: Unlimited memory growth as items are materialized for retry scenarios
- Silent Failures: Restart functionality is disabled without any indication
- Production Crashes: OutOfMemoryException in high-throughput scenarios
- Resource Exhaustion: System becomes unstable under load
Problematic Configuration
// ❌ PROBLEM: MaxMaterializedItems not specified (defaults to null)
var retryOptions = new PipelineRetryOptions(
maxRetryCount: 3,
baseDelay: TimeSpan.FromSeconds(1),
maxDelay: TimeSpan.FromMinutes(1));
// ❌ PROBLEM: MaxMaterializedItems explicitly set to null
var retryOptions = new PipelineRetryOptions(
maxRetryCount: 3,
baseDelay: TimeSpan.FromSeconds(1),
maxDelay: TimeSpan.FromMinutes(1),
maxMaterializedItems: null); // NP9501: Unbounded materialization
Solution: Set MaxMaterializedItems
// ✅ CORRECT: Set reasonable MaxMaterializedItems
var retryOptions = new PipelineRetryOptions(
maxRetryCount: 3,
baseDelay: TimeSpan.FromSeconds(1),
maxDelay: TimeSpan.FromMinutes(1),
maxMaterializedItems: 1000); // Bounded memory usage
// ✅ CORRECT: Use named parameters for clarity
var retryOptions = new PipelineRetryOptions
{
MaxRetryCount = 3,
BaseDelay = TimeSpan.FromSeconds(1),
MaxDelay = TimeSpan.FromMinutes(1),
MaxMaterializedItems = 1000 // Prevents unbounded growth
};
Choosing the Right MaxMaterializedItems Value
| Scenario | Recommended Value | Reason |
|---|---|---|
| Small items (< 1KB) | 1000-10000 | Low memory per item |
| Medium items (1KB-10KB) | 100-1000 | Balance memory and performance |
| Large items (> 10KB) | 10-100 | Prevent memory pressure |
| Memory-constrained environments | 10-50 | Conservative approach |
| High-throughput scenarios | 100-1000 | Depends on item size |
NP9502: Inappropriate Parallelism Configuration
ID: NP9502
Severity: Warning
Category: Performance
This analyzer detects inappropriate parallelism configurations that can cause resource contention, thread pool starvation, or suboptimal resource utilization in NPipeline pipelines.
Why This Matters
Inappropriate parallelism configuration causes:
- Resource Contention: Too much parallelism competes for limited resources
- Thread Pool Starvation: Excessive parallelism exhausts available threads
- Poor Performance: Suboptimal resource utilization reduces throughput
- System Instability: Overloaded system becomes unpredictable
Problematic Configuration
// ❌ PROBLEM: High parallelism for CPU-bound workloads
builder.AddTransform<CpuIntensiveTransform, Input, Output>("transform")
.WithParallelism(Environment.ProcessorCount * 4); // NP9502: Excessive parallelism
// ❌ PROBLEM: PreserveOrdering with high parallelism
var parallelOptions = new ParallelOptions(
maxDegreeOfParallelism: 16,
preserveOrdering: true); // NP9502: Ordering overhead with high parallelism
// ❌ PROBLEM: Single-threaded for CPU-bound work
builder.AddTransform<CpuTransform, Input, Output>("transform")
.WithParallelism(1); // NP9502: Underutilizing CPU resources
Solution: Match Parallelism to Workload
// ✅ CORRECT: Appropriate parallelism for CPU-bound workloads
builder.AddTransform<CpuIntensiveTransform, Input, Output>("transform")
.WithParallelism(Environment.ProcessorCount); // Match CPU cores
// ✅ CORRECT: Moderate parallelism for I/O-bound workloads
builder.AddTransform<DatabaseTransform, Input, Output>("transform")
.WithParallelism(Environment.ProcessorCount * 2); // I/O can handle more
// ✅ CORRECT: Disable PreserveOrdering with high parallelism
var parallelOptions = new ParallelOptions(
maxDegreeOfParallelism: 16,
preserveOrdering: false); // Better performance
Parallelism Guidelines
| Workload Type | Recommended Parallelism | PreserveOrdering |
|---|---|---|
| CPU-bound | Processor count | Only if required |
| I/O-bound | Processor count × 2 | Only if required |
| Mixed | Processor count × 1.5 | Only if required |
| Memory-intensive | Processor count ÷ 2 | Only if required |
NP9503: Batching Configuration Mismatch
ID: NP9503
Severity: Warning
Category: Performance
This analyzer detects batching configurations where batch sizes and timeouts are misaligned, causing either excessive latency from large batches or inefficient processing from small batches.
Why This Matters
Batching configuration mismatches cause:
- Poor Throughput: Small batches processed frequently reduce efficiency
- Excessive Latency: Large batches wait unnecessarily long
- Resource Waste: Inefficient use of system resources
- Unpredictable Performance: Inconsistent processing times
Problematic Configuration
// ❌ PROBLEM: Large batch size with short timeout
var batchingOptions = new BatchingOptions(
batchSize: 1000,
timeout: TimeSpan.FromMilliseconds(100)); // NP9503: Batch won't fill
// ❌ PROBLEM: Small batch size with long timeout
var batchingOptions = new BatchingOptions(
batchSize: 5,
timeout: TimeSpan.FromMinutes(1)); // NP9503: Unnecessary latency
// ❌ PROBLEM: Medium batch with disproportionate timeout
var batchingStrategy = new BatchingStrategy(
batchSize: 50,
maxWaitTime: TimeSpan.FromMilliseconds(10)); // NP9503: Too short for batch size
Solution: Align Batch Size and Timeout
// ✅ CORRECT: Balanced batching configuration
var batchingOptions = new BatchingOptions(
batchSize: 100,
timeout: TimeSpan.FromSeconds(1)); // Reasonable fill time
// ✅ CORRECT: Fast batching for small items
var batchingOptions = new BatchingOptions(
batchSize: 10,
timeout: TimeSpan.FromMilliseconds(100)); // Quick turnover
// ✅ CORRECT: Large batch with proportional timeout
var batchingStrategy = new BatchingStrategy(
batchSize: 1000,
maxWaitTime: TimeSpan.FromSeconds(5)); // Sufficient time to fill
Batching Configuration Guidelines
| Batch Size | Recommended Timeout | Use Case |
|---|---|---|
| 1-10 | 50-500ms | Low-latency scenarios |
| 10-100 | 500ms-2s | General purpose |
| 100-1000 | 1-10s | High-throughput scenarios |
| 1000+ | 5-30s | Batch processing systems |
NP9504: Timeout Configuration Issues
ID: NP9504
Severity: Warning
Category: Configuration
This analyzer detects inappropriate timeout configurations that can cause resource leaks, hanging operations, or inefficient resource utilization in NPipeline pipelines.
Why This Matters
Inappropriate timeout configurations cause:
- Resource Leaks: Operations that never timeout hold resources indefinitely
- Hanging Operations: Too long timeouts cause unresponsive systems
- Premature Failures: Too short timeouts cause unnecessary failures
- Poor User Experience: Inconsistent behavior and unpredictable responses
Problematic Configuration
// ❌ PROBLEM: Zero timeout for I/O operations
var resilientStrategy = new ResilientExecutionStrategy(
timeout: TimeSpan.Zero); // NP9504: Immediate failures
// ❌ PROBLEM: Very short timeout for I/O operations
builder.AddTransform<DatabaseTransform, Input, Output>("transform")
.WithTimeout(TimeSpan.FromMilliseconds(10)); // NP9504: Too short for database
// ❌ PROBLEM: Excessive timeout for CPU operations
builder.AddTransform<CpuTransform, Input, Output>("transform")
.WithTimeout(TimeSpan.FromHours(1)); // NP9504: Resource leak risk
// ❌ PROBLEM: Very long retry timeout
var retryOptions = new PipelineRetryOptions(
maxRetryCount: 3,
baseDelay: TimeSpan.FromSeconds(1),
maxDelay: TimeSpan.FromHours(2)); // NP9504: Excessive retry duration
Solution: Set Appropriate Timeouts
// ✅ CORRECT: Reasonable timeout for I/O operations
builder.AddTransform<DatabaseTransform, Input, Output>("transform")
.WithTimeout(TimeSpan.FromSeconds(30)); // Sufficient for database operations
// ✅ CORRECT: Appropriate timeout for CPU operations
builder.AddTransform<CpuTransform, Input, Output>("transform")
.WithTimeout(TimeSpan.FromMinutes(2)); // Reasonable for CPU work
// ✅ CORRECT: Balanced retry timeout
var retryOptions = new PipelineRetryOptions(
maxRetryCount: 3,
baseDelay: TimeSpan.FromSeconds(1),
maxDelay: TimeSpan.FromMinutes(5)); // Reasonable retry ceiling
Timeout Guidelines
| Operation Type | Recommended Timeout | Maximum Timeout |
|---|---|---|
| Database I/O | 5-60 seconds | 5 minutes |
| Network I/O | 1-30 seconds | 2 minutes |
| File I/O | 10-120 seconds | 10 minutes |
| CPU-bound | 30 seconds-5 minutes | 30 minutes |
| Retry operations | 1-10 minutes | 30 minutes |
Configuration Best Practices
General Guidelines
- Profile Before Optimizing: Measure actual performance when changing configuration
- Start Conservative: Begin with conservative values and adjust based on metrics
- Monitor Resource Usage: Watch memory, CPU, and thread pool metrics
- Test Under Load: Validate configuration with realistic workloads
Configuration Checklist
- Set
MaxMaterializedItemsto bound memory usage - Match parallelism to workload characteristics
- Align batch sizes with processing times
- Set appropriate timeouts for operation types
- Use efficient string operations in hot paths
- Avoid LINQ in high-frequency methods
- Replace anonymous objects with named types
Monitoring Configuration
// Add monitoring to validate configuration
public class MonitoredTransform : ITransformNode<Input, Output>
{
private readonly IMetrics _metrics;
protected override async Task<Output> ExecuteAsync(Input input, PipelineContext context, CancellationToken cancellationToken)
{
var stopwatch = Stopwatch.StartNew();
try
{
var result = await ProcessAsync(input, cancellationToken);
// Monitor processing time
_metrics.Histogram("transform.duration", stopwatch.ElapsedMilliseconds);
return result;
}
catch (Exception ex)
{
// Monitor errors
_metrics.Counter("transform.errors").Increment();
throw;
}
}
}
Configuration
Adjust analyzer severity in .editorconfig:
# Treat configuration issues as errors
dotnet_diagnostic.NP9501.severity = error
dotnet_diagnostic.NP9502.severity = warning
dotnet_diagnostic.NP9503.severity = warning
dotnet_diagnostic.NP9504.severity = warning
See Also
- Performance Analyzers - Write fast, non-blocking code
- Best Practice Analyzers - Follow framework design principles
- Data Processing Analyzers - Ensure data flows correctly