Skip to main content

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:

  1. Memory Leaks: Unlimited memory growth as items are materialized for retry scenarios
  2. Silent Failures: Restart functionality is disabled without any indication
  3. Production Crashes: OutOfMemoryException in high-throughput scenarios
  4. 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

ScenarioRecommended ValueReason
Small items (< 1KB)1000-10000Low memory per item
Medium items (1KB-10KB)100-1000Balance memory and performance
Large items (> 10KB)10-100Prevent memory pressure
Memory-constrained environments10-50Conservative approach
High-throughput scenarios100-1000Depends 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:

  1. Resource Contention: Too much parallelism competes for limited resources
  2. Thread Pool Starvation: Excessive parallelism exhausts available threads
  3. Poor Performance: Suboptimal resource utilization reduces throughput
  4. 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 TypeRecommended ParallelismPreserveOrdering
CPU-boundProcessor countOnly if required
I/O-boundProcessor count × 2Only if required
MixedProcessor count × 1.5Only if required
Memory-intensiveProcessor count ÷ 2Only 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:

  1. Poor Throughput: Small batches processed frequently reduce efficiency
  2. Excessive Latency: Large batches wait unnecessarily long
  3. Resource Waste: Inefficient use of system resources
  4. 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 SizeRecommended TimeoutUse Case
1-1050-500msLow-latency scenarios
10-100500ms-2sGeneral purpose
100-10001-10sHigh-throughput scenarios
1000+5-30sBatch 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:

  1. Resource Leaks: Operations that never timeout hold resources indefinitely
  2. Hanging Operations: Too long timeouts cause unresponsive systems
  3. Premature Failures: Too short timeouts cause unnecessary failures
  4. 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 TypeRecommended TimeoutMaximum Timeout
Database I/O5-60 seconds5 minutes
Network I/O1-30 seconds2 minutes
File I/O10-120 seconds10 minutes
CPU-bound30 seconds-5 minutes30 minutes
Retry operations1-10 minutes30 minutes

Configuration Best Practices

General Guidelines

  1. Profile Before Optimizing: Measure actual performance when changing configuration
  2. Start Conservative: Begin with conservative values and adjust based on metrics
  3. Monitor Resource Usage: Watch memory, CPU, and thread pool metrics
  4. Test Under Load: Validate configuration with realistic workloads

Configuration Checklist

  • Set MaxMaterializedItems to 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