Skip to content

feat(messaging): add message expiration pattern#384

Merged
JerrettDavis merged 1 commit into
mainfrom
feature/message-expiration-pattern
May 27, 2026
Merged

feat(messaging): add message expiration pattern#384
JerrettDavis merged 1 commit into
mainfrom
feature/message-expiration-pattern

Conversation

@JerrettDavis

Copy link
Copy Markdown
Owner

Closes #383.

Summary

  • Adds the Message Expiration enterprise integration pattern with fluent runtime APIs and a [GenerateMessageExpiration] source-generated factory path.
  • Adds an order deadline example with IServiceCollection integration, production catalog coverage, docs, README tables, and user guide entries.
  • Adds TinyBDD coverage for runtime behavior, generator diagnostics/output, examples, catalog accounting, and benchmark coverage.
  • Adds BenchmarkDotNet coverage for fluent/generated construction and execution, with validated result rows in docs.
  • Pins Microsoft.CodeAnalysis.CSharp to 5.0.0 so source generators load under the Windows SDK compiler used by the solution build.

Validation

  • dotnet restore PatternKit.slnx --force-evaluate
  • dotnet build PatternKit.slnx --configuration Release --no-restore -m:1
  • dotnet test test\PatternKit.Tests\PatternKit.Tests.csproj --configuration Release --no-build --logger "console;verbosity=minimal" -p:TestTfmsInParallel=false
  • dotnet test test\PatternKit.Generators.Tests\PatternKit.Generators.Tests.csproj --configuration Release --no-build --logger "console;verbosity=minimal" -p:TestTfmsInParallel=false
  • dotnet test test\PatternKit.Examples.Tests\PatternKit.Examples.Tests.csproj --configuration Release --no-build --logger "console;verbosity=minimal" -p:TestTfmsInParallel=false
  • dotnet run -c Release --framework net10.0 --no-build --project benchmarks\PatternKit.Benchmarks -- --filter PatternKit.Benchmarks.Messaging.MessageExpirationBenchmarks* --artifacts artifacts\benchmarks-messageexpiration --join
  • git diff --check

Copilot AI review requested due to automatic review settings May 27, 2026 05:49
@github-actions

Copy link
Copy Markdown
Contributor

⚠️ Deprecation Warning: The deny-licenses option is deprecated for possible removal in the next major release. For more information, see issue 997.

Dependency Review

✅ No vulnerabilities or license issues or OpenSSF Scorecard issues found.

Scanned Files

None

@github-actions

Copy link
Copy Markdown
Contributor

Test Results

    1 files      1 suites   2m 19s ⏱️
1 045 tests 1 045 ✅ 0 💤 0 ❌
1 050 runs  1 050 ✅ 0 💤 0 ❌

Results for commit 874c2c5.

@codecov

codecov Bot commented May 27, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 98.21429% with 4 lines in your changes missing coverage. Please review.
✅ Project coverage is 95.61%. Comparing base (234079c) to head (874c2c5).

Files with missing lines Patch % Lines
...it.Core/Messaging/Reliability/MessageExpiration.cs 97.46% 2 Missing ⚠️
...Generators/Messaging/MessageExpirationGenerator.cs 97.61% 2 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #384      +/-   ##
==========================================
+ Coverage   89.55%   95.61%   +6.06%     
==========================================
  Files         518      522       +4     
  Lines       42034    42258     +224     
  Branches     6070     6104      +34     
==========================================
+ Hits        37645    40407    +2762     
+ Misses       1997     1851     -146     
+ Partials     2392        0    -2392     
Flag Coverage Δ
unittests 95.61% <98.21%> (+6.06%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@github-actions

Copy link
Copy Markdown
Contributor

🔍 PR Validation Results

Version: ``

✅ Validation Steps

  • Build solution
  • Run tests
  • Build documentation
  • Dry-run NuGet packaging

📊 Artifacts

Dry-run artifacts have been uploaded and will be available for 7 days.


This comment was automatically generated by the PR validation workflow.

@github-actions

Copy link
Copy Markdown
Contributor

Code Coverage

Summary
  Generated on: 05/27/2026 - 05:54:53
  Coverage date: 05/27/2026 - 05:53:34 - 05/27/2026 - 05:54:42
  Parser: MultiReport (9x Cobertura)
  Assemblies: 4
  Classes: 1587
  Files: 639
  Line coverage: 94.5%
  Covered lines: 41430
  Uncovered lines: 2366
  Coverable lines: 43796
  Total lines: 95824
  Branch coverage: 75.5% (12173 of 16121)
  Covered branches: 12173
  Total branches: 16121
  Method coverage: 95.9% (8301 of 8650)
  Full method coverage: 88.1% (7626 of 8650)
  Covered methods: 8301
  Fully covered methods: 7626
  Total methods: 8650

PatternKit.Core                                                                                                     95.4%
  PatternKit.Application.ActivityTracking.ActivityGateState                                                          100%
  PatternKit.Application.ActivityTracking.ActivityLease                                                              100%
  PatternKit.Application.ActivityTracking.ActivityRecord                                                             100%
  PatternKit.Application.ActivityTracking.ActivityTracker                                                            100%
  PatternKit.Application.AntiCorruption.AntiCorruptionLayer<T1, T2>                                                 90.4%
  PatternKit.Application.AntiCorruption.AntiCorruptionResult<T>                                                      100%
  PatternKit.Application.AuditLog.AuditLogAppendResult<T>                                                           85.7%
  PatternKit.Application.AuditLog.InMemoryAuditLog<T1, T2>                                                          95.4%
  PatternKit.Application.DataMapping.DataMapper<T1, T2>                                                             94.6%
  PatternKit.Application.DataMapping.DataMapperError                                                                  90%
  PatternKit.Application.DataMapping.DataMapperResult<T>                                                            84.6%
  PatternKit.Application.DomainEvents.DomainEventDispatcher<T>                                                      95.4%
  PatternKit.Application.DomainEvents.DomainEventDispatchResult                                                      100%
  PatternKit.Application.EventSourcing.EventStoreAppendResult                                                        100%
  PatternKit.Application.EventSourcing.InMemoryEventStore<T1, T2>                                                   97.9%
  PatternKit.Application.EventSourcing.StoredEvent<T1, T2>                                                            80%
  PatternKit.Application.FeatureToggles.FeatureToggleDecision                                                       87.5%
  PatternKit.Application.FeatureToggles.FeatureToggleRule<T>                                                         100%
  PatternKit.Application.FeatureToggles.FeatureToggleSet<T>                                                         96.9%
  PatternKit.Application.IdentityMap.IdentityMap<T1, T2>                                                             100%
  PatternKit.Application.IdentityMap.IdentityMapResult<T>                                                           92.8%
  PatternKit.Application.MaterializedViews.MaterializedView<T1, T2>                                                 98.4%
  PatternKit.Application.Repository.InMemoryRepository<T1, T2>                                                      92.8%
  PatternKit.Application.Repository.RepositoryResult<T>                                                             93.3%
  PatternKit.Application.ServiceLayer.ServiceLayerOperation<T1, T2>                                                 96.7%
  PatternKit.Application.ServiceLayer.ServiceLayerResult<T>                                                         94.7%
  PatternKit.Application.ServiceLayer.ServiceLayerRule<T>                                                            100%
  PatternKit.Application.Specification.Specification<T>                                                              100%
  PatternKit.Application.Specification.SpecificationRegistry<T>                                                     93.3%
  PatternKit.Application.TableDataGateway.InMemoryTableDataGateway<T1, T2>                                            86%
  PatternKit.Application.TableDataGateway.TableGatewayResult<T>                                                     82.3%
  PatternKit.Application.TransactionScript.TransactionScript<T1, T2>                                                  97%
  PatternKit.Application.TransactionScript.TransactionScriptError                                                     90%
  PatternKit.Application.TransactionScript.TransactionScriptResult<T>                                                100%
  PatternKit.Application.UnitOfWork.UnitOfWork                                                                      90.9%
  PatternKit.Application.UnitOfWork.UnitOfWorkResult                                                                94.7%
  PatternKit.Application.UnitOfWork.UnitOfWorkRollbackResult                                                         100%
  PatternKit.Application.UnitOfWork.UnitOfWorkStep                                                                   100%

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds the Message Expiration enterprise integration pattern to PatternKit, including a fluent runtime API, a new Roslyn source generator path, an end-to-end example with DI wiring, tests, docs, and benchmark/catal​og coverage updates.

Changes:

  • Introduces MessageExpiration<TPayload> runtime API + result type, with TinyBDD coverage for stamping/evaluation behavior.
  • Adds [GenerateMessageExpiration] + MessageExpirationGenerator with generator tests and diagnostics registration.
  • Updates pattern/example catalogs, documentation, README tables, benchmark coverage matrix, and package pinning for Roslyn (Microsoft.CodeAnalysis.CSharp).

Reviewed changes

Copilot reviewed 32 out of 32 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
test/PatternKit.Tests/packages.lock.json Updates lockfile for multi-target test restore (incl. net10.0).
test/PatternKit.Tests/Messaging/Reliability/MessageExpirationTests.cs Adds runtime behavior tests for message expiration stamping/evaluation.
test/PatternKit.Generators.Tests/packages.lock.json Updates generator-test lockfile for new Roslyn pin and net10.0.
test/PatternKit.Generators.Tests/MessageExpirationGeneratorTests.cs Adds generator output/diagnostic tests for message expiration generation.
test/PatternKit.Generators.Tests/AbstractionsAttributeCoverageTests.cs Extends attribute coverage to include GenerateMessageExpirationAttribute.
test/PatternKit.Examples.Tests/ProductionReadiness/PatternKitPatternCatalogTests.cs Updates expected catalog entries/counts to include Message Expiration.
test/PatternKit.Examples.Tests/ProductionReadiness/PatternKitBenchmarkCoverageTests.cs Updates expected benchmark route-result totals after adding the new pattern.
test/PatternKit.Examples.Tests/packages.lock.json Updates examples-test lockfile (incl. net10.0).
test/PatternKit.Examples.Tests/Messaging/OrderMessageExpirationExampleTests.cs Adds example-level tests for fluent + generated expiration and DI registration.
src/PatternKit.Generators/packages.lock.json Updates generator package lockfile (netstandard2.0) for Roslyn pin.
src/PatternKit.Generators/Messaging/MessageExpirationGenerator.cs Adds incremental generator emitting MessageExpiration<T> factory source.
src/PatternKit.Generators/AnalyzerReleases.Unshipped.md Documents new generator diagnostics PKMEXP001/PKMEXP002.
src/PatternKit.Generators.Abstractions/Messaging/MessageExpirationAttributes.cs Adds [GenerateMessageExpiration] attribute API surface and options.
src/PatternKit.Examples/ProductionReadiness/PatternKitPatternCatalog.cs Registers new pattern with source/tests/docs/example paths for coverage auditing.
src/PatternKit.Examples/ProductionReadiness/PatternKitExampleCatalog.cs Registers new “Order Message Expiration” example descriptor.
src/PatternKit.Examples/Messaging/OrderMessageExpirationExample.cs Adds order-deadline example (fluent + generated) and IServiceCollection integration.
src/PatternKit.Examples/DependencyInjection/PatternKitExampleServiceCollectionExtensions.cs Wires the new example into the consolidated examples DI surface.
src/PatternKit.Core/Messaging/Reliability/MessageExpiration.cs Adds core implementation of Message Expiration policy + evaluation result.
README.md Updates pattern counts/table and adds benchmark rows for Message Expiration.
docs/patterns/toc.yml Adds Message Expiration to patterns TOC.
docs/patterns/messaging/message-expiration.md Adds pattern documentation and usage snippet.
docs/guides/pattern-coverage.md Adds Message Expiration to the coverage guide table.
docs/guides/benchmarks.md Adds Message Expiration benchmark rows.
docs/guides/benchmark-results.md Adds Message Expiration rows + updates totals and generator coverage table.
docs/generators/toc.yml Adds Message Expiration generator doc to generators TOC.
docs/generators/message-expiration.md Adds generator documentation and option table.
docs/generators/index.md Adds Message Expiration to generator index table.
docs/examples/toc.yml Adds Order Message Expiration to examples TOC.
docs/examples/order-message-expiration.md Adds example documentation and DI usage snippet.
Directory.Packages.props Pins Microsoft.CodeAnalysis.CSharp to 5.0.0 for generator loading compatibility.
benchmarks/PatternKit.Benchmarks/Messaging/MessageExpirationBenchmarks.cs Adds BenchmarkDotNet coverage for fluent vs generated construction/execution routes.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

return message.Headers.TryGetDateTimeOffset(_headerName, out var expiresAt) ? expiresAt : null;
}

/// <summary>Returns a new message with an expiration deadline based on the configured or supplied TTL.</summary>
@JerrettDavis
JerrettDavis merged commit 59f890b into main May 27, 2026
13 checks passed
@JerrettDavis
JerrettDavis deleted the feature/message-expiration-pattern branch May 27, 2026 06:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add Message Expiration enterprise integration pattern

2 participants