Skip to content

Conversation

@alexeyzimarev
Copy link
Contributor

@alexeyzimarev alexeyzimarev commented Dec 10, 2025

User description

  • Moved KurrentDB-related files to the right path
  • Performance optimisations in subscriptions

PR Type

Enhancement, Tests, Documentation


Description

  • Core Performance Optimizations: Implemented 5 critical optimizations reducing allocations and improving throughput:
    • Optimized HandlingResults with single-field pattern (158x faster for single results)
    • Lazy-initialized ContextItems dictionary (104 bytes saved per message)
    • Replaced logging scope Dictionary with KeyValuePair array (5x faster, 3x less allocation)
    • Optimized CancellationTokenSource creation with guards to avoid unnecessary linked tokens
    • Changed channel batch return type from T[] to IReadOnlyList<T> to avoid array allocations
  • Comprehensive Benchmark Suite: Added 8 new benchmark classes validating performance improvements:
    • ImplementedOptimizationsValidationBenchmarks - validates all implemented optimizations
    • OptimizationComparisonBenchmarks - compares current vs optimized implementations
    • ContextAllocationBenchmarks - measures context creation overhead
    • AllocationHotspotsBenchmarks - identifies common allocation patterns
    • ChannelBatchingBenchmarks - compares 6 batching approaches
    • CheckpointBenchmarks, FilterPipelineBenchmarks, SubscriptionMessageProcessingBenchmarks
  • Performance Documentation: Added comprehensive analysis and validation reports:
    • PERFORMANCE_ANALYSIS.md - documents 13 identified issues with severity levels
    • VALIDATION_REPORT.md - confirms implementation of P0/P1 optimizations
    • BENCHMARK_RESULTS_SUMMARY.md - executive summary with priority matrix
    • README.md - benchmarks suite documentation and usage guide
  • Project Structure Updates: Reorganized samples from ESDB to KurrentDB naming convention and updated project references
  • Code Modernization: Updated CommitPositionSequence to use modern C# tuple syntax

Diagram Walkthrough

flowchart LR
  A["Subscription<br/>Processing"] -->|Optimize| B["HandlingResults<br/>Single-field pattern"]
  A -->|Optimize| C["ContextItems<br/>Lazy Dictionary"]
  A -->|Optimize| D["Logging Scope<br/>KeyValuePair Array"]
  A -->|Optimize| E["CancellationTokenSource<br/>Guards"]
  A -->|Optimize| F["Channel Batching<br/>IReadOnlyList"]
  B -->|Validate| G["Benchmark Suite"]
  C -->|Validate| G
  D -->|Validate| G
  E -->|Validate| G
  F -->|Validate| G
  G -->|Document| H["Performance Reports"]
Loading

File Walkthrough

Relevant files
Tests
22 files
ImplementedOptimizationsValidationBenchmarks.cs
Benchmark validation for implemented performance optimizations

src/Benchmarks/Benchmarks/ImplementedOptimizationsValidationBenchmarks.cs

  • New benchmark file validating performance improvements from
    implemented optimizations
  • Compares OLD implementations (before changes) with NEW implementations
    (after changes)
  • Tests HandlingResults, ContextItems, logging scope, and
    CancellationTokenSource optimizations
  • Includes old implementation classes for baseline comparison
+212/-0 
OptimizationComparisonBenchmarks.cs
Optimization comparison benchmarks for P0 items                   

src/Benchmarks/Benchmarks/OptimizationComparisonBenchmarks.cs

  • New benchmark comparing current vs optimized implementations
  • Tests ContextItems lazy initialization and HandlingResults
    single-result optimization
  • Demonstrates potential improvements from P0 priority optimizations
  • Includes optimized implementation classes for comparison
+157/-0 
ContextAllocationBenchmarks.cs
Context allocation overhead benchmarks                                     

src/Benchmarks/Benchmarks/ContextAllocationBenchmarks.cs

  • New benchmark focusing on context allocation overhead
  • Tests MessageConsumeContext creation, ContextItems usage, and
    HandlingResults
  • Measures allocation patterns for typed context wrappers and full
    message processing simulation
  • Addresses P0 issues related to context and handling results
+161/-0 
AllocationHotspotsBenchmarks.cs
Allocation hotspots and string operation benchmarks           

src/Benchmarks/Benchmarks/AllocationHotspotsBenchmarks.cs

  • New benchmark for common allocation hotspots in the codebase
  • Tests dictionary allocations, string formatting, LINQ usage, and
    CancellationTokenSource creation
  • Compares different approaches (interpolation vs concat vs
    StringBuilder)
  • Identifies performance characteristics of frequently-used operations
+131/-0 
FilterPipelineBenchmarks.cs
Filter pipeline processing benchmarks                                       

src/Benchmarks/Benchmarks/FilterPipelineBenchmarks.cs

  • New benchmark for filter pipeline processing performance
  • Tests simple pipe, async handling filter, and multi-filter pipelines
  • Measures overhead of filter chains and batch processing
  • Includes configurable message count parameter
+135/-0 
CheckpointBenchmarks.cs
Checkpoint commit operation benchmarks                                     

src/Benchmarks/Benchmarks/CheckpointBenchmarks.cs

  • New benchmark for checkpoint commit operations
  • Tests sequential and gapped checkpoint commits
  • Measures CommitPositionSequence operations and gap detection
  • Addresses P2 issue with LINQ usage in checkpoint processing
+129/-0 
SubscriptionMessageProcessingBenchmarks.cs
Subscription message processing throughput benchmarks       

src/Benchmarks/Benchmarks/SubscriptionMessageProcessingBenchmarks.cs

  • New benchmark for subscription message processing throughput
  • Tests single message handling, batch processing, and context creation
  • Validates P0 optimizations from performance analysis
  • Includes configurable message count parameter
+112/-0 
ChannelBatchingBenchmarks.cs
Channel batching optimization approach benchmarks               

src/Benchmarks/Benchmarks/ChannelBatchingBenchmarks.cs

  • New benchmark testing 6 different approaches to channel batching
  • Compares List.ToArray(), CollectionsMarshal.AsSpan(), ArrayPool, and
    other alternatives
  • Configurable batch sizes (10, 50, 100) for comprehensive testing
  • Helps determine optimal solution for P2 optimization
+83/-0   
Benchmarks.ChannelBatchingBenchmarks-report.html
Channel batching benchmark results report                               

src/Benchmarks/Benchmarks/BenchmarkDotNet.Artifacts/results/Benchmarks.ChannelBatchingBenchmarks-report.html

  • HTML benchmark report for channel batching optimization approaches
  • Compares 6 different batching strategies across batch sizes (10, 50,
    100)
  • Shows performance metrics (Mean, Error, StdDev, Allocation) for each
    approach
  • Demonstrates that CollectionsMarshal.AsSpan() and direct List return
    have zero allocation
+52/-0   
Benchmarks.CheckpointBenchmarks-report-github.md
Checkpoint benchmarks results report                                         

src/Benchmarks/Benchmarks/BenchmarkDotNet.Artifacts/results/Benchmarks.CheckpointBenchmarks-report-github.md

  • Markdown benchmark report for checkpoint operations
  • Shows performance metrics for sequential and gapped checkpoint commits
  • Measures CommitPositionSequence operations at different position
    counts (10, 100)
  • Provides baseline data for P2 optimization decisions
+26/-0   
Benchmarks.ChannelBatchingBenchmarks-report-github.md
Channel batching benchmark results report                               

src/Benchmarks/Benchmarks/BenchmarkDotNet.Artifacts/results/Benchmarks.ChannelBatchingBenchmarks-report-github.md

  • Added benchmark results report for channel batching performance
    testing
  • Contains performance metrics comparing alternative array handling
    approaches (ArrayPool, CollectionsMarshal, pre-allocated arrays)
  • Shows measurements across different batch sizes (10, 50, 100)
  • Displays execution time, memory allocation, and garbage collection
    statistics
+40/-0   
Benchmarks.ImplementedOptimizationsValidationBenchmarks-report.html
Implemented optimizations validation benchmark report       

src/Benchmarks/Benchmarks/BenchmarkDotNet.Artifacts/results/Benchmarks.ImplementedOptimizationsValidationBenchmarks-report.html

  • Added HTML benchmark report for implemented optimizations validation
  • Contains performance comparison between old and new implementations
  • Measures HandlingResults, ContextItems, logging scope, and
    CancellationTokenSource optimizations
  • Shows significant improvements in execution time and memory allocation
+43/-0   
Benchmarks.AllocationHotspotsBenchmarks-report.html
Allocation hotspots benchmark analysis report                       

src/Benchmarks/Benchmarks/BenchmarkDotNet.Artifacts/results/Benchmarks.AllocationHotspotsBenchmarks-report.html

  • Added HTML report for allocation hotspots benchmark analysis
  • Compares various allocation patterns for logging scopes, activity
    names, LINQ operations, and CancellationTokenSource
  • Provides baseline measurements for optimization decisions
+44/-0   
Benchmarks.ImplementedOptimizationsValidationBenchmarks-report-github.md
Implemented optimizations GitHub-formatted benchmark report

src/Benchmarks/Benchmarks/BenchmarkDotNet.Artifacts/results/Benchmarks.ImplementedOptimizationsValidationBenchmarks-report-github.md

  • Added GitHub-formatted markdown report for implemented optimizations
  • Shows side-by-side comparison of old vs new implementations
  • Demonstrates significant performance improvements (e.g.,
    HandlingResults: 725ns to 4.3ns for single result)
  • Includes memory allocation ratios and garbage collection metrics
+26/-0   
Benchmarks.CheckpointBenchmarks-report.html
Checkpoint benchmarks performance report                                 

src/Benchmarks/Benchmarks/BenchmarkDotNet.Artifacts/results/Benchmarks.CheckpointBenchmarks-report.html

  • Added HTML report for checkpoint benchmarks
  • Measures sequential checkpoint commits, gap detection, and
    CommitPositionSequence operations
  • Tests with different position counts (10, 100)
  • Provides baseline metrics for checkpoint performance analysis
+43/-0   
Benchmarks.ContextAllocationBenchmarks-report.html
Context allocation benchmarks performance report                 

src/Benchmarks/Benchmarks/BenchmarkDotNet.Artifacts/results/Benchmarks.ContextAllocationBenchmarks-report.html

  • Added HTML report for context allocation benchmarks
  • Measures MessageConsumeContext creation, ContextItems usage,
    HandlingResults, and full message processing
  • Provides allocation metrics and garbage collection statistics
  • Establishes baseline for context-related optimizations
+39/-0   
Benchmarks.AllocationHotspotsBenchmarks-report-github.md
Allocation hotspots GitHub-formatted benchmark report       

src/Benchmarks/Benchmarks/BenchmarkDotNet.Artifacts/results/Benchmarks.AllocationHotspotsBenchmarks-report-github.md

  • Added GitHub-formatted markdown report for allocation hotspots
  • Compares dictionary vs KeyValuePair array for logging scopes (79%
    reduction)
  • Shows string formatting alternatives and LINQ vs manual iteration
    patterns
  • Includes CancellationTokenSource and common allocation comparisons
+27/-0   
Benchmarks.OptimizationComparisonBenchmarks-report.html
Optimization comparison benchmarks report                               

src/Benchmarks/Benchmarks/BenchmarkDotNet.Artifacts/results/Benchmarks.OptimizationComparisonBenchmarks-report.html

  • Added HTML report for optimization comparison benchmarks
  • Compares current vs optimized implementations for ContextItems and
    HandlingResults
  • Measures single and multiple handler scenarios
  • Provides allocation and performance metrics for optimization
    validation
+36/-0   
Benchmarks.SubscriptionMessageProcessingBenchmarks-report-github.md
Subscription message processing GitHub-formatted benchmark report

src/Benchmarks/Benchmarks/BenchmarkDotNet.Artifacts/results/Benchmarks.SubscriptionMessageProcessingBenchmarks-report-github.md

  • Added GitHub-formatted markdown report for subscription message
    processing benchmarks
  • Documents benchmark execution issues with async operations
  • Shows test parameters for single, 10, and 100 message counts
  • Lists all benchmarks with issues encountered during execution
+33/-0   
Benchmarks.ContextAllocationBenchmarks-report-github.md
Context allocation GitHub-formatted benchmark report         

src/Benchmarks/Benchmarks/BenchmarkDotNet.Artifacts/results/Benchmarks.ContextAllocationBenchmarks-report-github.md

  • Added GitHub-formatted markdown report for context allocation
    benchmarks
  • Shows context creation baseline and various allocation scenarios
  • Measures ContextItems usage, HandlingResults, and full message
    processing
  • Provides allocation ratios for optimization impact assessment
+22/-0   
Benchmarks.SubscriptionMessageProcessingBenchmarks-report.html
Subscription message processing benchmark report                 

src/Benchmarks/Benchmarks/BenchmarkDotNet.Artifacts/results/Benchmarks.SubscriptionMessageProcessingBenchmarks-report.html

  • Added HTML report for subscription message processing benchmarks
  • Documents benchmark execution with async operations
  • Tests single message handler invocation, batch processing, and context
    creation
  • Includes multiple message count parameters (1, 10, 100)
+39/-0   
Benchmarks.OptimizationComparisonBenchmarks-report-github.md
Optimization comparison GitHub-formatted benchmark report

src/Benchmarks/Benchmarks/BenchmarkDotNet.Artifacts/results/Benchmarks.OptimizationComparisonBenchmarks-report-github.md

  • Added GitHub-formatted markdown report for optimization comparisons
  • Compares ContextItems implementations (eager vs lazy dictionary)
  • Shows HandlingResults improvements (single and multiple results)
  • Demonstrates performance parity with optimized implementations
+19/-0   
Enhancement
8 files
AsyncHandlingFilter.cs
Optimize CancellationTokenSource creation with guards       

src/Core/src/Eventuous.Subscriptions/Filters/AsyncHandlingFilter.cs

  • Optimized CancellationTokenSource creation with guards to avoid
    unnecessary linked token sources
  • Only creates linked CTS when both tokens can be canceled and are
    different
  • Improved error handling with nested try-catch blocks
  • Ensures proper disposal of CancellationTokenSource in finally block
+45/-23 
EventHandlingResult.cs
Optimize HandlingResults with single-field pattern             

src/Core/src/Eventuous.Subscriptions/Handlers/EventHandlingResult.cs

  • Replaced ConcurrentBag with optimized single nullable field + List
    fallback
  • Optimized for common case of single handler (zero allocation)
  • Replaced all LINQ operations with manual iteration to avoid enumerator
    allocations
  • Removed unnecessary System.Collections.Concurrent import
+50/-8   
ContextItems.cs
Lazy initialize ContextItems dictionary                                   

src/Core/src/Eventuous.Subscriptions/Context/ContextItems.cs

  • Implemented lazy initialization of internal Dictionary
  • Dictionary is now nullable and only allocated when first item is added
  • Updated GetItem and TryGetItem methods to handle null dictionary
  • Saves 104 bytes per message when items are not used
+11/-2   
ChannelExtensions.cs
Change channel batch return type to IReadOnlyList               

src/Core/src/Eventuous.Subscriptions/Channels/ChannelExtensions.cs

  • Changed batch return type from T[] to IReadOnlyList for better
    flexibility
  • Replaced buffer.ToArray() with buffer.AsReadOnly() to avoid array
    allocation
  • Updated method signatures in ReadBatches and ReadAllBatches to use new
    return type
  • Reduces allocation overhead in channel batching operations
+4/-4     
CommitPositionSequence.cs
Modernize CommitPositionSequence LINQ syntax                         

src/Core/src/Eventuous.Subscriptions/Checkpoints/CommitPositionSequence.cs

  • Replaced Tuple.Create with tuple expression syntax in Zip operation
  • Changed tuple field access from Item1/Item2 to named fields
    position1/position2
  • Updated null check from == null to == default for tuple comparison
  • Improved code readability and modern C# syntax
+5/-5     
EventSubscription.cs
Replace logging scope Dictionary with KeyValuePair array 

src/Core/src/Eventuous.Subscriptions/EventSubscription.cs

  • Replaced Dictionary with KeyValuePair
    object>[] for logging scope
  • Provides 5x faster performance and 3x less allocation for logging
    scope creation
  • Updated scope initialization to use array of KeyValuePair tuples
  • Reduces per-message allocation overhead
+5/-4     
ChannelWorkers.cs
Update BatchedChannelWorker to use IReadOnlyList                 

src/Core/src/Eventuous.Subscriptions/Channels/ChannelWorkers.cs

  • Updated BatchedChannelWorker constructor parameter type from
    ProcessElement to ProcessElement>
  • Aligns with channel batching API changes to use IReadOnlyList instead
    of arrays
  • Maintains backward compatibility through interface abstraction
+1/-1     
CheckpointCommitHandler.cs
Update CheckpointCommitHandler to use IReadOnlyList           

src/Core/src/Eventuous.Subscriptions/Checkpoints/CheckpointCommitHandler.cs

  • Changed Process method parameter type from CommitPosition[] to
    IReadOnlyList
  • Aligns with channel batching API changes to use IReadOnlyList instead
    of arrays
  • Maintains same functionality with more flexible interface
+1/-1     
Documentation
4 files
PERFORMANCE_ANALYSIS.md
Comprehensive performance analysis and optimization guide

src/Core/src/Eventuous.Subscriptions/perf/PERFORMANCE_ANALYSIS.md

  • Comprehensive performance and memory analysis document for
    Eventuous.Subscriptions
  • Documents 13 identified performance issues with severity levels and
    recommendations
  • Includes benchmark results validating 4 critical optimizations (158x
    faster HandlingResults, 5x faster logging)
  • Provides implementation guidance and priority matrix for all
    optimizations
+736/-0 
VALIDATION_REPORT.md
Performance optimizations validation and implementation report

src/Core/src/Eventuous.Subscriptions/perf/VALIDATION_REPORT.md

  • Validation report documenting all implemented P0/P1 optimizations
  • Confirms 158x faster HandlingResults, 5x faster logging scope, 104B
    savings from lazy init
  • Provides implementation details and benchmark results for each
    optimization
  • Includes recommendations for remaining P2/P3 optimizations
+358/-0 
Benchmarks.BENCHMARK_RESULTS_SUMMARY.md
Benchmark results summary and optimization priority matrix

src/Benchmarks/Benchmarks/BenchmarkDotNet.Artifacts/results/Benchmarks.BENCHMARK_RESULTS_SUMMARY.md

  • Executive summary of all benchmark results validating performance
    optimizations
  • Confirms critical wins: 158x faster HandlingResults, 5x faster
    logging, 104B lazy init savings
  • Identifies optimizations to skip (LINQ replacement, wrapper pooling)
  • Provides implementation priority matrix and estimated impact analysis
README.md
Comprehensive benchmarks documentation and usage guide     

src/Benchmarks/Benchmarks/README.md

  • Added comprehensive documentation for the Eventuous Subscriptions
    benchmarks suite
  • Documents four active benchmark classes with their purposes and
    metrics
  • Explains disabled benchmarks (CheckpointBenchmarks,
    FilterPipelineBenchmarks) and reasons for disabling
  • Provides instructions for running benchmarks, interpreting results,
    and continuous benchmarking practices
  • Includes troubleshooting guide and benchmark maintenance guidelines
+267/-0 
Configuration changes
7 files
docker-compose.yml
Disabled EventStore service in docker-compose                       

samples/kurrentdb/docker-compose.yml

  • Commented out EventStore database service configuration
  • Kept MongoDB service active and unchanged
  • Maintains docker-compose structure for other services
+16/-16 
Eventuous.slnx
Renamed ESDB samples folder to KurrentDB                                 

Eventuous.slnx

  • Renamed sample folder from /Samples/Esdb/ to /Samples/KurrentDB/
  • Updated project paths from samples/esdb/ to samples/kurrentdb/
  • Affects Bookings.Domain, Bookings.Payments, and Bookings projects
+4/-4     
KurrentDB Bookings.run.xml
Added KurrentDB Bookings run configuration                             

.run/KurrentDB Bookings.run.xml

  • Added new run configuration for KurrentDB Bookings sample
  • Configures launch settings for Samples.Esdb.Bookings profile
  • Sets target framework to net10.0 and output type to executable
+18/-0   
Benchmarks.csproj
Added source generators and disabled slow benchmarks         

src/Benchmarks/Benchmarks/Benchmarks.csproj

  • Added project references to source generators
    (Eventuous.Subscriptions.Generators, Eventuous.Shared.Generators)
  • Added FilterPipelineBenchmarks.cs and CheckpointBenchmarks.cs to
    Compile Remove list
  • Disables problematic async benchmark classes due to excessive runtime
+4/-0     
Bookings.Payments.csproj
Updated Postgres sample to use KurrentDB shared code         

samples/postgres/Bookings.Payments/Bookings.Payments.csproj

  • Updated compile include paths from esdb to kurrentdb directory
  • Changes affect Domain and Application shared code references
+2/-2     
Bookings.Domain.csproj
Updated Postgres domain sample to use KurrentDB shared code

samples/postgres/Bookings.Domain/Bookings.Domain.csproj

  • Updated compile include paths from esdb to kurrentdb directory
  • Changes affect shared domain code references
+2/-2     
Bookings.csproj
Added executable output type to KurrentDB Bookings             

samples/kurrentdb/Bookings/Bookings.csproj

  • Added OutputType property set to exe to explicitly define executable
    output
+1/-0     
Formatting
1 files
Bookings.csproj
Formatting adjustment in Postgres Bookings project             

samples/postgres/Bookings/Bookings.csproj

  • Minor formatting change to ProjectReference element (added space
    before closing tag)
+1/-1     
Additional files
48 files
Bookings.Domain.csproj [link]   
Booking.cs [link]   
BookingEvents.cs [link]   
BookingId.cs [link]   
BookingState.cs [link]   
Money.cs [link]   
RoomId.cs [link]   
Services.cs [link]   
StayPeriod.cs [link]   
CommandApi.cs [link]   
CommandService.cs [link]   
Bookings.Payments.csproj [link]   
Money.cs [link]   
Payment.cs [link]   
PaymentEvents.cs [link]   
Logging.cs [link]   
Mongo.cs [link]   
Payments.cs [link]   
Program.cs [link]   
Registrations.cs [link]   
appsettings.json [link]   
.dockerignore [link]   
BookingsCommandService.cs [link]   
BookingsQueryService.cs [link]   
Commands.cs [link]   
BookingDocument.cs [link]   
BookingStateProjection.cs [link]   
MyBookings.cs [link]   
MyBookingsProjection.cs [link]   
Dockerfile [link]   
CommandApi.cs [link]   
CommandApiWithCustomResult.cs [link]   
QueryApi.cs [link]   
Mongo.cs [link]   
Payments.cs [link]   
Program.cs [link]   
Registrations.cs [link]   
appsettings.json [link]   
Pulumi.dev.yaml [link]   
Pulumi.yaml [link]   
index.ts [link]   
package.json [link]   
tsconfig.json [link]   
__inputs.json [link]   
datasources.yml [link]   
prometheus.yml [link]   
DynamicType.cs +0/-37   
BENCHMARK_RESULTS_SUMMARY.md +336/-0 

@qodo-free-for-open-source-projects
Copy link
Contributor

qodo-free-for-open-source-projects bot commented Dec 10, 2025

PR Compliance Guide 🔍

Below is a summary of compliance checks for this PR:

Security Compliance
🟢
No security concerns identified No security vulnerabilities detected by AI analysis. Human verification advised for critical code.
Ticket Compliance
🎫 No ticket provided

[Generating...]

Codebase Duplication Compliance
🟢
No codebase code duplication found No new components were introduced in the PR code
Custom Compliance
🟢
Generic: Comprehensive Audit Trails

Objective: To create a detailed and reliable record of critical system actions for security analysis
and compliance.

Status: Passed

Learn more about managing compliance generic rules or creating your own custom rules

Generic: Meaningful Naming and Self-Documenting Code

Objective: Ensure all identifiers clearly express their purpose and intent, making code
self-documenting

Status: Passed

Learn more about managing compliance generic rules or creating your own custom rules

Generic: Secure Error Handling

Objective: To prevent the leakage of sensitive system information through error messages while
providing sufficient detail for internal debugging.

Status: Passed

Learn more about managing compliance generic rules or creating your own custom rules

Generic: Secure Logging Practices

Objective: To ensure logs are useful for debugging and auditing without exposing sensitive
information like PII, PHI, or cardholder data.

Status: Passed

Learn more about managing compliance generic rules or creating your own custom rules

Generic: Security-First Input Validation and Data Handling

Objective: Ensure all data inputs are validated, sanitized, and handled securely to prevent
vulnerabilities

Status: Passed

Learn more about managing compliance generic rules or creating your own custom rules

Generic: Robust Error Handling and Edge Case Management

Objective: Ensure comprehensive error handling that provides meaningful context and graceful
degradation

Status:
Silent exception handling: The code catches TaskCanceledException and OperationCanceledException and returns silently
without logging, which may hide legitimate cancellation issues that should be tracked

Referred Code
} catch (TaskCanceledException) {
    return;
} catch (OperationCanceledException) {
    return;
} catch (Exception e) {

Learn more about managing compliance generic rules or creating your own custom rules

  • Update
Compliance status legend 🟢 - Fully Compliant
🟡 - Partial Compliant
🔴 - Not Compliant
⚪ - Requires Further Human Verification
🏷️ - Compliance label

@qodo-free-for-open-source-projects
Copy link
Contributor

qodo-free-for-open-source-projects bot commented Dec 10, 2025

PR Code Suggestions ✨

Explore these optional code suggestions:

CategorySuggestion                                                                                                                                    Impact
High-level
Avoid committing generated benchmark artifacts
Suggestion Impact:The suggestion was implemented by removing the generated benchmark artifact files. The diff shows two HTML and markdown report files being deleted (their entire content removed, leaving only empty files or minimal content), which directly addresses the suggestion to not commit these generated files.

code diff:

# File: src/Benchmarks/Benchmarks/BenchmarkDotNet.Artifacts/results/Benchmarks.ImplementedOptimizationsValidationBenchmarks-report.html
@@ -1,43 +1 @@
-<!DOCTYPE html>
-<html lang='en'>
-<head>
-<meta charset='utf-8' />
-<title>Benchmarks.ImplementedOptimizationsValidationBenchmarks-20251210-134759</title>
 
-<style type="text/css">
-	table { border-collapse: collapse; display: block; width: 100%; overflow: auto; }
-	td, th { padding: 6px 13px; border: 1px solid #ddd; text-align: right; }
-	tr { background-color: #fff; border-top: 1px solid #ccc; }
-	tr:nth-child(even) { background: #f8f8f8; }
-</style>
-</head>
-<body>
-<pre><code>
-BenchmarkDotNet v0.14.0, macOS Sequoia 15.6.1 (24G90) [Darwin 24.6.0]
-Apple M2 Ultra, 1 CPU, 24 logical and 24 physical cores
-.NET SDK 10.0.100
-  [Host]     : .NET 10.0.0 (10.0.25.52411), Arm64 RyuJIT AdvSIMD
-  Job-ERDHQH : .NET 10.0.0 (10.0.25.52411), Arm64 RyuJIT AdvSIMD
-</code></pre>
-<pre><code>IterationCount=5  WarmupCount=3  
-</code></pre>
-
-<table>
-<thead><tr><th>Method                                    </th><th>Mean   </th><th>Error</th><th>StdDev</th><th>Median </th><th>Ratio</th><th>RatioSD</th><th>Gen0</th><th>Gen1</th><th>Allocated</th><th>Alloc Ratio</th>
-</tr>
-</thead><tbody><tr><td>&#39;OLD: HandlingResults ConcurrentBag (single)&#39;</td><td>725.3432 ns</td><td>358.2608 ns</td><td>93.0392 ns</td><td>679.7854 ns</td><td>1.012</td><td>0.16</td><td>0.1411</td><td>0.0706</td><td>1184 B</td><td>1.00</td>
-</tr><tr><td>&#39;NEW: HandlingResults Optimized (single)&#39;</td><td>4.3629 ns</td><td>0.0833 ns</td><td>0.0129 ns</td><td>4.3599 ns</td><td>0.006</td><td>0.00</td><td>0.0076</td><td>-</td><td>64 B</td><td>0.05</td>
-</tr><tr><td>&#39;OLD: HandlingResults ConcurrentBag (3 results)&#39;</td><td>1,031.5773 ns</td><td>177.1218 ns</td><td>27.4098 ns</td><td>1,021.8274 ns</td><td>1.439</td><td>0.16</td><td>0.1926</td><td>0.0954</td><td>1624 B</td><td>1.37</td>
-</tr><tr><td>&#39;NEW: HandlingResults Optimized (3 results)&#39;</td><td>62.4788 ns</td><td>3.1560 ns</td><td>0.8196 ns</td><td>62.4005 ns</td><td>0.087</td><td>0.01</td><td>0.0401</td><td>-</td><td>336 B</td><td>0.28</td>
-</tr><tr><td>&#39;OLD: ContextItems eager Dictionary (not used)&#39;</td><td>10.9220 ns</td><td>0.4695 ns</td><td>0.1219 ns</td><td>10.9095 ns</td><td>0.015</td><td>0.00</td><td>0.0124</td><td>-</td><td>104 B</td><td>0.09</td>
-</tr><tr><td>&#39;NEW: ContextItems lazy Dictionary (not used)&#39;</td><td>2.8759 ns</td><td>0.0791 ns</td><td>0.0205 ns</td><td>2.8781 ns</td><td>0.004</td><td>0.00</td><td>0.0029</td><td>-</td><td>24 B</td><td>0.02</td>
-</tr><tr><td>&#39;OLD: ContextItems eager Dictionary (used)&#39;</td><td>37.2149 ns</td><td>1.6123 ns</td><td>0.4187 ns</td><td>37.1999 ns</td><td>0.052</td><td>0.01</td><td>0.0315</td><td>-</td><td>264 B</td><td>0.22</td>
-</tr><tr><td>&#39;NEW: ContextItems lazy Dictionary (used)&#39;</td><td>36.6316 ns</td><td>2.1428 ns</td><td>0.3316 ns</td><td>36.7412 ns</td><td>0.051</td><td>0.01</td><td>0.0315</td><td>-</td><td>264 B</td><td>0.22</td>
-</tr><tr><td>&#39;OLD: Logging scope with Dictionary&#39;</td><td>36.7883 ns</td><td>1.4737 ns</td><td>0.2281 ns</td><td>36.8573 ns</td><td>0.051</td><td>0.01</td><td>0.0258</td><td>-</td><td>216 B</td><td>0.18</td>
-</tr><tr><td>&#39;NEW: Logging scope with KeyValuePair array&#39;</td><td>8.9584 ns</td><td>0.1901 ns</td><td>0.0494 ns</td><td>8.9539 ns</td><td>0.012</td><td>0.00</td><td>0.0086</td><td>-</td><td>72 B</td><td>0.06</td>
-</tr><tr><td>&#39;OLD: Always create linked CTS&#39;</td><td>4.9044 ns</td><td>0.1118 ns</td><td>0.0290 ns</td><td>4.9187 ns</td><td>0.007</td><td>0.00</td><td>0.0057</td><td>-</td><td>48 B</td><td>0.04</td>
-</tr><tr><td>&#39;NEW: Guarded CTS creation (same tokens)&#39;</td><td>0.0052 ns</td><td>0.0041 ns</td><td>0.0006 ns</td><td>0.0054 ns</td><td>0.000</td><td>0.00</td><td>-</td><td>-</td><td>-</td><td>0.00</td>
-</tr><tr><td>&#39;NEW: Guarded CTS creation (non-cancelable)&#39;</td><td>0.0049 ns</td><td>0.0172 ns</td><td>0.0045 ns</td><td>0.0031 ns</td><td>0.000</td><td>0.00</td><td>-</td><td>-</td><td>-</td><td>0.00</td>
-</tr></tbody></table>
-</body>
-</html>

# File: src/Benchmarks/Benchmarks/BenchmarkDotNet.Artifacts/results/Benchmarks.ChannelBatchingBenchmarks-report-github.md
@@ -1,40 +1 @@
-```
 
-BenchmarkDotNet v0.14.0, macOS Sequoia 15.6.1 (24G90) [Darwin 24.6.0]
-Apple M2 Ultra, 1 CPU, 24 logical and 24 physical cores
-.NET SDK 10.0.100
-  [Host]     : .NET 10.0.0 (10.0.25.52411), Arm64 RyuJIT AdvSIMD
-  Job-QMNUBS : .NET 10.0.0 (10.0.25.52411), Arm64 RyuJIT AdvSIMD
-  Job-ERDHQH : .NET 10.0.0 (10.0.25.52411), Arm64 RyuJIT AdvSIMD
-
-IterationCount=5  WarmupCount=3  
-
-```
-| Method                                           | Job        | InvocationCount | UnrollFactor | BatchSize | Mean       | Error       | StdDev     | Median     | Ratio | RatioSD | Gen0   | Allocated | Alloc Ratio |
-|------------------------------------------------- |----------- |---------------- |------------- |---------- |-----------:|------------:|-----------:|-----------:|------:|--------:|-------:|----------:|------------:|
-| **&#39;Alternative 2b: ArrayPool with return overhead&#39;** | **Job-QMNUBS** | **1**               | **1**            | **10**        | **24.8000 ns** | **142.7182 ns** | **37.0635 ns** |  **0.0000 ns** |     **?** |       **?** |      **-** |         **-** |           **?** |
-|                                                  |            |                 |              |           |            |             |            |            |       |         |        |           |             |
-| &#39;Current: List.ToArray()&#39;                        | Job-ERDHQH | Default         | 16           | 10        |  5.5116 ns |   0.1332 ns |  0.0346 ns |  5.5131 ns | 1.000 |    0.01 | 0.0076 |      64 B |        1.00 |
-| &#39;Alternative 1: CollectionsMarshal.AsSpan()&#39;     | Job-ERDHQH | Default         | 16           | 10        |  0.0000 ns |   0.0000 ns |  0.0000 ns |  0.0000 ns | 0.000 |    0.00 |      - |         - |        0.00 |
-| &#39;Alternative 2: ArrayPool rent/copy&#39;             | Job-ERDHQH | Default         | 16           | 10        | 10.2304 ns |   0.3892 ns |  0.1011 ns | 10.2198 ns | 1.856 |    0.02 | 0.0105 |      88 B |        1.38 |
-| &#39;Alternative 3: Pre-allocated array with CopyTo&#39; | Job-ERDHQH | Default         | 16           | 10        |  6.2246 ns |   0.2015 ns |  0.0312 ns |  6.2225 ns | 1.129 |    0.01 | 0.0076 |      64 B |        1.00 |
-| &#39;Alternative 4: Direct List (no copy)&#39;           | Job-ERDHQH | Default         | 16           | 10        |  0.0017 ns |   0.0091 ns |  0.0024 ns |  0.0000 ns | 0.000 |    0.00 |      - |         - |        0.00 |
-| &#39;Alternative 5: IReadOnlyList wrapper&#39;           | Job-ERDHQH | Default         | 16           | 10        |  4.1141 ns |   0.0671 ns |  0.0174 ns |  4.1077 ns | 0.746 |    0.01 | 0.0029 |      24 B |        0.38 |
-|                                                  |            |                 |              |           |            |             |            |            |       |         |        |           |             |
-| **&#39;Alternative 2b: ArrayPool with return overhead&#39;** | **Job-QMNUBS** | **1**               | **1**            | **50**        | **83.2000 ns** | **376.4130 ns** | **97.7533 ns** | **41.0000 ns** |     **?** |       **?** |      **-** |         **-** |           **?** |
-|                                                  |            |                 |              |           |            |             |            |            |       |         |        |           |             |
-| &#39;Current: List.ToArray()&#39;                        | Job-ERDHQH | Default         | 16           | 50        | 12.0382 ns |   0.1448 ns |  0.0376 ns | 12.0435 ns | 1.000 |    0.00 | 0.0268 |     224 B |        1.00 |
-| &#39;Alternative 1: CollectionsMarshal.AsSpan()&#39;     | Job-ERDHQH | Default         | 16           | 50        |  0.0000 ns |   0.0000 ns |  0.0000 ns |  0.0000 ns | 0.000 |    0.00 |      - |         - |        0.00 |
-| &#39;Alternative 2: ArrayPool rent/copy&#39;             | Job-ERDHQH | Default         | 16           | 50        | 19.3441 ns |   0.3516 ns |  0.0913 ns | 19.3115 ns | 1.607 |    0.01 | 0.0335 |     280 B |        1.25 |
-| &#39;Alternative 3: Pre-allocated array with CopyTo&#39; | Job-ERDHQH | Default         | 16           | 50        | 12.8857 ns |   0.2359 ns |  0.0613 ns | 12.8699 ns | 1.070 |    0.01 | 0.0268 |     224 B |        1.00 |
-| &#39;Alternative 4: Direct List (no copy)&#39;           | Job-ERDHQH | Default         | 16           | 50        |  0.0000 ns |   0.0000 ns |  0.0000 ns |  0.0000 ns | 0.000 |    0.00 |      - |         - |        0.00 |
-| &#39;Alternative 5: IReadOnlyList wrapper&#39;           | Job-ERDHQH | Default         | 16           | 50        |  4.0931 ns |   0.0715 ns |  0.0186 ns |  4.0939 ns | 0.340 |    0.00 | 0.0029 |      24 B |        0.11 |
-|                                                  |            |                 |              |           |            |             |            |            |       |         |        |           |             |
-| **&#39;Alternative 2b: ArrayPool with return overhead&#39;** | **Job-QMNUBS** | **1**               | **1**            | **100**       |  **0.0000 ns** |   **0.0000 ns** |  **0.0000 ns** |  **0.0000 ns** |     **?** |       **?** |      **-** |         **-** |           **?** |
-|                                                  |            |                 |              |           |            |             |            |            |       |         |        |           |             |
-| &#39;Current: List.ToArray()&#39;                        | Job-ERDHQH | Default         | 16           | 100       | 21.4336 ns |   0.5448 ns |  0.0843 ns | 21.4648 ns | 1.000 |    0.00 | 0.0507 |     424 B |        1.00 |
-| &#39;Alternative 1: CollectionsMarshal.AsSpan()&#39;     | Job-ERDHQH | Default         | 16           | 100       |  0.0000 ns |   0.0000 ns |  0.0000 ns |  0.0000 ns | 0.000 |    0.00 |      - |         - |        0.00 |
-| &#39;Alternative 2: ArrayPool rent/copy&#39;             | Job-ERDHQH | Default         | 16           | 100       | 30.6041 ns |   0.7195 ns |  0.1869 ns | 30.6931 ns | 1.428 |    0.01 | 0.0641 |     536 B |        1.26 |
-| &#39;Alternative 3: Pre-allocated array with CopyTo&#39; | Job-ERDHQH | Default         | 16           | 100       | 23.3649 ns |   0.2840 ns |  0.0738 ns | 23.3650 ns | 1.090 |    0.00 | 0.0507 |     424 B |        1.00 |
-| &#39;Alternative 4: Direct List (no copy)&#39;           | Job-ERDHQH | Default         | 16           | 100       |  0.0000 ns |   0.0000 ns |  0.0000 ns |  0.0000 ns | 0.000 |    0.00 |      - |         - |        0.00 |
-| &#39;Alternative 5: IReadOnlyList wrapper&#39;           | Job-ERDHQH | Default         | 16           | 100       |  4.0679 ns |   0.2249 ns |  0.0348 ns |  4.0845 ns | 0.190 |    0.00 | 0.0029 |      24 B |        0.06 |

Do not commit generated benchmark result files from the
BenchmarkDotNet.Artifacts directory. Instead, add this directory to .gitignore
to prevent bloating the repository.

Examples:

src/Benchmarks/Benchmarks/BenchmarkDotNet.Artifacts/results/Benchmarks.ImplementedOptimizationsValidationBenchmarks-report.html [1-43]
src/Benchmarks/Benchmarks/BenchmarkDotNet.Artifacts/results/Benchmarks.ChannelBatchingBenchmarks-report-github.md [1-40]

Solution Walkthrough:

Before:

# .gitignore (before)
# ... (other entries)
# Does not ignore BenchmarkDotNet artifacts

# Files committed in the PR
+ src/Benchmarks/Benchmarks/BenchmarkDotNet.Artifacts/results/Benchmarks.ChannelBatchingBenchmarks-report.html
+ src/Benchmarks/Benchmarks/BenchmarkDotNet.Artifacts/results/Benchmarks.ChannelBatchingBenchmarks-report-github.md
+ src/Benchmarks/Benchmarks/BenchmarkDotNet.Artifacts/results/Benchmarks.ImplementedOptimizationsValidationBenchmarks-report.html
+ src/Benchmarks/Benchmarks/BenchmarkDotNet.Artifacts/results/Benchmarks.ImplementedOptimizationsValidationBenchmarks-report-github.md
# ... and 12 other generated report files

After:

# .gitignore (after)
# ... (other entries)
BenchmarkDotNet.Artifacts/

# Files committed in the PR
# The generated report files under src/Benchmarks/Benchmarks/BenchmarkDotNet.Artifacts/ are no longer committed.
# Key findings are summarized in manually created markdown files like:
# - src/Core/src/Eventuous.Subscriptions/perf/PERFORMANCE_ANALYSIS.md
# - src/Core/src/Eventuous.Subscriptions/perf/VALIDATION_REPORT.md
Suggestion importance[1-10]: 7

__

Why: The suggestion correctly identifies that generated benchmark artifacts are being committed, which is against best practices and harms long-term repository health.

Medium
Possible issue
Fix memory leak in benchmark

Fix a memory leak in the Alternative2_ArrayPool benchmark by using
IterationSetup and IterationCleanup to correctly manage the lifecycle of the
rented array.

src/Benchmarks/Benchmarks/ChannelBatchingBenchmarks.cs [38-43]

+private int[]? _rentedArrayForAlt2;
+
+[IterationSetup(Target = nameof(Alternative2_ArrayPool))]
+public void SetupArrayPool() {
+    _rentedArrayForAlt2 = ArrayPool<int>.Shared.Rent(_buffer.Count);
+}
+
 [Benchmark(Description = "Alternative 2: ArrayPool rent/copy")]
 public int[] Alternative2_ArrayPool() {
-    var array = ArrayPool<int>.Shared.Rent(_buffer.Count);
-    _buffer.CopyTo(array);
-    return array; // Note: caller must return to pool
+    _buffer.CopyTo(_rentedArrayForAlt2!);
+    return _rentedArrayForAlt2!;
 }
 
+[IterationCleanup(Target = nameof(Alternative2_ArrayPool))]
+public void CleanupArrayPool() {
+    if (_rentedArrayForAlt2 != null) {
+        ArrayPool<int>.Shared.Return(_rentedArrayForAlt2);
+        _rentedArrayForAlt2 = null;
+    }
+}
+

[To ensure code accuracy, apply this suggestion manually]

Suggestion importance[1-10]: 6

__

Why: The suggestion correctly identifies a memory leak in the Alternative2_ArrayPool benchmark, which would lead to inaccurate measurements, and proposes a proper fix using IterationSetup and IterationCleanup.

Low
General
Update launch profile name for consistency
Suggestion Impact:The commit directly implements the suggested change by updating the LAUNCH_PROFILE_NAME value from "Samples.Esdb.Bookings" to "Samples.KurrentDB.Bookings" on line 6 of the configuration file.

code diff:

-    <option name="LAUNCH_PROFILE_NAME" value="Samples.Esdb.Bookings" />
+    <option name="LAUNCH_PROFILE_NAME" value="Samples.KurrentDB.Bookings" />

Update the launch profile name in the run configuration from
Samples.Esdb.Bookings to Samples.KurrentDB.Bookings to align with the esdb to
kurrentdb renaming.

.run/KurrentDB Bookings.run.xml [5]

-<option name="LAUNCH_PROFILE_NAME" value="Samples.Esdb.Bookings" />
+<option name="LAUNCH_PROFILE_NAME" value="Samples.KurrentDB.Bookings" />

[Suggestion processed]

Suggestion importance[1-10]: 5

__

Why: The suggestion correctly identifies an inconsistent launch profile name in the new run configuration, which was likely missed during the esdb to kurrentdb refactoring, ensuring the configuration works as expected.

Low
  • Update

@github-actions
Copy link

github-actions bot commented Dec 10, 2025

Test Results

 51 files  + 34   51 suites  +34   32m 55s ⏱️ + 22m 6s
282 tests + 10  282 ✅ + 10  0 💤 ±0  0 ❌ ±0 
849 runs  +566  849 ✅ +566  0 💤 ±0  0 ❌ ±0 

Results for commit 32f4d9d. ± Comparison against base commit 2f9d974.

This pull request removes 5 and adds 15 tests. Note that renamed tests count towards both.
Eventuous.Tests.Azure.ServiceBus.IsSerialisableByServiceBus ‑ Passes(12/3/2025 7:25:25 AM +00:00)
Eventuous.Tests.Azure.ServiceBus.IsSerialisableByServiceBus ‑ Passes(12/3/2025 7:25:25 AM)
Eventuous.Tests.Azure.ServiceBus.IsSerialisableByServiceBus ‑ Passes(81afcab6-084f-4b49-92a9-7564158e5743)
Eventuous.Tests.Subscriptions.SequenceTests ‑ ShouldReturnFirstBefore(CommitPosition { Position: 0, Sequence: 1, Timestamp: 2025-12-03T07:25:25.5801568+00:00 }, CommitPosition { Position: 0, Sequence: 2, Timestamp: 2025-12-03T07:25:25.5801568+00:00 }, CommitPosition { Position: 0, Sequence: 4, Timestamp: 2025-12-03T07:25:25.5801568+00:00 }, CommitPosition { Position: 0, Sequence: 6, Timestamp: 2025-12-03T07:25:25.5801568+00:00 }, CommitPosition { Position: 0, Sequence: 2, Timestamp: 2025-12-03T07:25:25.5801568+00:00 })
Eventuous.Tests.Subscriptions.SequenceTests ‑ ShouldReturnFirstBefore(CommitPosition { Position: 0, Sequence: 1, Timestamp: 2025-12-03T07:25:25.5801568+00:00 }, CommitPosition { Position: 0, Sequence: 2, Timestamp: 2025-12-03T07:25:25.5801568+00:00 }, CommitPosition { Position: 0, Sequence: 6, Timestamp: 2025-12-03T07:25:25.5801568+00:00 }, CommitPosition { Position: 0, Sequence: 8, Timestamp: 2025-12-03T07:25:25.5801568+00:00 }, CommitPosition { Position: 0, Sequence: 2, Timestamp: 2025-12-03T07:25:25.5801568+00:00 })
Eventuous.Tests.Azure.ServiceBus.IsSerialisableByServiceBus ‑ Passes(12/10/2025 6:41:54 PM +00:00)
Eventuous.Tests.Azure.ServiceBus.IsSerialisableByServiceBus ‑ Passes(12/10/2025 6:41:54 PM)
Eventuous.Tests.Azure.ServiceBus.IsSerialisableByServiceBus ‑ Passes(12/10/2025 6:42:01 PM +00:00)
Eventuous.Tests.Azure.ServiceBus.IsSerialisableByServiceBus ‑ Passes(12/10/2025 6:42:01 PM)
Eventuous.Tests.Azure.ServiceBus.IsSerialisableByServiceBus ‑ Passes(12/10/2025 6:48:52 PM +00:00)
Eventuous.Tests.Azure.ServiceBus.IsSerialisableByServiceBus ‑ Passes(12/10/2025 6:48:52 PM)
Eventuous.Tests.Azure.ServiceBus.IsSerialisableByServiceBus ‑ Passes(7a7a8c28-2fbe-4133-affe-5325645c1e49)
Eventuous.Tests.Azure.ServiceBus.IsSerialisableByServiceBus ‑ Passes(7d141241-9a1c-4dc2-948a-46af3e65fc34)
Eventuous.Tests.Azure.ServiceBus.IsSerialisableByServiceBus ‑ Passes(b0238c01-287c-45fb-8f7a-602437e07bed)
Eventuous.Tests.Subscriptions.SequenceTests ‑ ShouldReturnFirstBefore(CommitPosition { Position: 0, Sequence: 1, Timestamp: 2025-12-10T18:41:54.2005371+00:00 }, CommitPosition { Position: 0, Sequence: 2, Timestamp: 2025-12-10T18:41:54.2005371+00:00 }, CommitPosition { Position: 0, Sequence: 4, Timestamp: 2025-12-10T18:41:54.2005371+00:00 }, CommitPosition { Position: 0, Sequence: 6, Timestamp: 2025-12-10T18:41:54.2005371+00:00 }, CommitPosition { Position: 0, Sequence: 2, Timestamp: 2025-12-10T18:41:54.2005371+00:00 })
…

♻️ This comment has been updated with latest results.

alexeyzimarev and others added 3 commits December 10, 2025 19:37
Co-authored-by: qodo-merge-for-open-source[bot] <189517486+qodo-merge-for-open-source[bot]@users.noreply.github.com>
@qodo-free-for-open-source-projects
Copy link
Contributor

😔 An error occurred while trying to generate Jira ticket requirements.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants