Releases: FoundatioFx/Foundatio
v13.0.1
v13.0.1
This is a major release with 368 files changed across the entire Foundatio codebase. Here are the themes that define v13:
- Reliability & Correctness: Dozens of race conditions, deadlocks, and disposal issues have been hunted down and fixed across queues, messaging, caching, and timers. Cancellation tokens are now properly linked to disposal for clean shutdown, and poison messages are gracefully handled instead of crashing consumers.
- Consistent Error Handling: Every subsystem now has its own exception type (
QueueException,MessageBusException,SerializerException) so consumers get predictable, catchable errors regardless of the underlying provider. These feature-specific exceptions are automatically excluded from resilience policy retries. - API Normalization: Cache TTL behavior, serializer validation, and expiration return values have been normalized across all implementations -- no more provider-specific quirks.
- Null Safety: A comprehensive NRT audit eliminated
null!suppressions across the codebase, fixing latent null bugs and adding proper nullable attributes. The API surface now accurately communicates nullability contracts. - Modern .NET: Dropped
netstandard2.0in favor ofnet8.0+net10.0. Replaced DeepCloner with the actively-maintained FastCloner.ScheduledTimernow usesTimeProviderfor testability. - Documentation Overhaul: Foundatio now has a dedicated documentation site with comprehensive guides, source code links, and real-world examples for every subsystem.
Documentation Site
Foundatio v13 ships with a brand-new documentation site covering every subsystem with guides, configuration examples, and direct source code links. Key additions:
- New docs site built with VitePress (
061bd763) - Source code links added to every subsystem: caching (
8f6d37c1), queues (bb9af714), messaging (59cc2f57), locks (10241465), jobs (7df97b13), serialization (8819ba09), storage (bf2eb1b9) - Comprehensive hybrid caching documentation with RedisHybridCacheClient examples (
2fc124df,0791b496) - Cache stampede protection patterns (
a6cfd75c) - Delayed message delivery and distributed tracing guide (
da2c6162) - RabbitMQ delayed delivery and delayed-exchange plugin deprecation notes (#490)
- Redis read routing and replica support guide (
6860a0c1) - Redis replication lag risk documentation (
98323dbe) - Queue names vs. queue IDs explainer (
456389ed) - Cancellation token behavior clarification (
70a63d12) - Cache expiration differences across implementations (
1853daee) - Enhanced XML doc comments across all core interfaces (
7fdad859) - Updated job samples (
3e003a86) and added sample projects + benchmarks to the solution (160dd74f) - Added Foundatio.Mediator links to README and docs (
b8f0eba1)
Breaking Changes
- Dropped
netstandard2.0target: Foundatio now targetsnet8.0andnet10.0only. Consumers on .NET Framework or older runtimes must stay on v12.x. by @niemyjski in4c6aefed,a1089422 - Normalized
ICacheClient.IncrementAsyncTTL behavior: Increment operations now consistently apply the TTL parameter across all implementations. RemovedListRemoveAsyncExpiresInargument to align with all other Remove methods. by @niemyjski in #434 - Normalized
ICacheClientreturn values for expiration:GetExpirationAsyncreturns consistent values across implementations. by @niemyjski in #432 - Normalized
ISerializerargument validation: All serializer implementations now consistently validate arguments and throwArgumentException/ArgumentNullException. by @niemyjski in #440 - Added
QueueException: Queue operations now throwQueueExceptionfor queue-specific errors. Guard added against reusing behavior instances. by @niemyjski in #448 MessageBusIdandQueueIdchanged to init-only properties: These properties can no longer be set after construction. by @niemyjski inb73bf128- Removed obsolete
Set/SetAdd/SetRemovemethods from cache extensions: These were renamed toList*in v9.0.0 (Nov 2019) and have been[Obsolete]for 6+ years. by @niemyjski in150beed5 - Removed obsolete single-parameter
GetFileStreamAsyncoverload: Deprecated in v10.7.0 (Jan 2024) whenStreamModewas added. Use the overload acceptingStreamModeandCancellationToken. by @niemyjski in037baae5 - Comprehensive NRT (Nullable Reference Types) null-safety audit: Eliminated
null!suppressions, fixed latent null bugs, and added nullable attributes across the codebase. Return types and parameters may have changed nullability. by @niemyjski in #484, #498
- Make AcquireAsync throw on failure to fix the silent-null lock footgun by @ejsmith in #508
- Default JobResult.Message to empty string by @ejsmith in #507
- fix: abandon queue entry when GetQueueEntryLockAsync throws by @niemyjski in #509
Added
- Upgrade to xUnit v3 with
Foundatio.Xunit.v3: Test infrastructure upgraded to xUnit v3. NewFoundatio.Xunit.v3package with retry test attributes (RetryFactAttribute,RetryTheoryAttribute) for automatic retry of flaky tests. The existingFoundatio.Xunitpackage continues to support xUnit v2. by @niemyjski in #431 - Memory-limited in-memory cache:
InMemoryCacheClientnow supportsMaxMemorySizewith per-entry size limits and intelligent eviction when memory budgets are exceeded. by @niemyjski, @copilot in #400 - Poison message handling for queues and message bus: Deserialization failures in queues and the message bus are now gracefully handled as poison messages instead of crashing consumers. Dead letter logging improved. by @niemyjski in #455
SerializerException: New exception type for serialization-specific errors, enabling targeted error handling. by @niemyjski inb314a052MessageBusException: Consistent error handling for messaging operations with improved delayed message delivery. by @niemyjski in #443QueueDeletedevent onIQueue<T>: Consumers can now subscribe to queue deletion notifications. by @niemyjski in #447- OpenTelemetry error recording: Added
Activity.AddExceptionpolyfill for recording exceptions in distributed traces across all target frameworks. by @niemyjski in #446 - Synchronous
IResiliencePolicymethods: Added sync overloads (Execute,ExecuteAsync) alongside existing async methods. by @ejsmith in #445 - Feature-specific exceptions excluded from resilience policy retries:
QueueException,MessageBusException,StorageException,SerializerException, andCacheExceptionare no longer retried by resilience policies. by @niemyjski in318fa1a0 GetAllExpirationsAsyncandSetAllExpirationsAsynconICacheClient: Bulk expiration read/write support with improved test coverage. by @niemyjski in #426- Option to dispose underlying scoped implementations: Scoped cache/queue/etc. wrappers can now optionally dispose their underlying instances. by @niemyjski in #412
- Job status description:
JobStatusnow supports aDescriptionproperty. by @ejsmith in [fdcc1442](htt...
v13.0.0
v13.0.0
This is a major release with 368 files changed across the entire Foundatio codebase. Here are the themes that define v13:
- Reliability & Correctness: Dozens of race conditions, deadlocks, and disposal issues have been hunted down and fixed across queues, messaging, caching, and timers. Cancellation tokens are now properly linked to disposal for clean shutdown, and poison messages are gracefully handled instead of crashing consumers.
- Consistent Error Handling: Every subsystem now has its own exception type (
QueueException,MessageBusException,SerializerException) so consumers get predictable, catchable errors regardless of the underlying provider. These feature-specific exceptions are automatically excluded from resilience policy retries. - API Normalization: Cache TTL behavior, serializer validation, and expiration return values have been normalized across all implementations -- no more provider-specific quirks.
- Null Safety: A comprehensive NRT audit eliminated
null!suppressions across the codebase, fixing latent null bugs and adding proper nullable attributes. The API surface now accurately communicates nullability contracts. - Modern .NET: Dropped
netstandard2.0in favor ofnet8.0+net10.0. Replaced DeepCloner with the actively-maintained FastCloner.ScheduledTimernow usesTimeProviderfor testability. - Documentation Overhaul: Foundatio now has a dedicated documentation site with comprehensive guides, source code links, and real-world examples for every subsystem.
Documentation Site
Foundatio v13 ships with a brand-new documentation site covering every subsystem with guides, configuration examples, and direct source code links. Key additions:
- New docs site built with VitePress (
061bd763) - Source code links added to every subsystem: caching (
8f6d37c1), queues (bb9af714), messaging (59cc2f57), locks (10241465), jobs (7df97b13), serialization (8819ba09), storage (bf2eb1b9) - Comprehensive hybrid caching documentation with RedisHybridCacheClient examples (
2fc124df,0791b496) - Cache stampede protection patterns (
a6cfd75c) - Delayed message delivery and distributed tracing guide (
da2c6162) - RabbitMQ delayed delivery and delayed-exchange plugin deprecation notes (#490)
- Redis read routing and replica support guide (
6860a0c1) - Redis replication lag risk documentation (
98323dbe) - Queue names vs. queue IDs explainer (
456389ed) - Cancellation token behavior clarification (
70a63d12) - Cache expiration differences across implementations (
1853daee) - Enhanced XML doc comments across all core interfaces (
7fdad859) - Updated job samples (
3e003a86) and added sample projects + benchmarks to the solution (160dd74f) - Added Foundatio.Mediator links to README and docs (
b8f0eba1)
Breaking Changes
- Dropped
netstandard2.0target: Foundatio now targetsnet8.0andnet10.0only. Consumers on .NET Framework or older runtimes must stay on v12.x. by @niemyjski in4c6aefed,a1089422 - Normalized
ICacheClient.IncrementAsyncTTL behavior: Increment operations now consistently apply the TTL parameter across all implementations. RemovedListRemoveAsyncExpiresInargument to align with all other Remove methods. by @niemyjski in #434 - Normalized
ICacheClientreturn values for expiration:GetExpirationAsyncreturns consistent values across implementations. by @niemyjski in #432 - Normalized
ISerializerargument validation: All serializer implementations now consistently validate arguments and throwArgumentException/ArgumentNullException. by @niemyjski in #440 - Added
QueueException: Queue operations now throwQueueExceptionfor queue-specific errors. Guard added against reusing behavior instances. by @niemyjski in #448 MessageBusIdandQueueIdchanged to init-only properties: These properties can no longer be set after construction. by @niemyjski inb73bf128- Removed obsolete
Set/SetAdd/SetRemovemethods from cache extensions: These were renamed toList*in v9.0.0 (Nov 2019) and have been[Obsolete]for 6+ years. by @niemyjski in150beed5 - Removed obsolete single-parameter
GetFileStreamAsyncoverload: Deprecated in v10.7.0 (Jan 2024) whenStreamModewas added. Use the overload acceptingStreamModeandCancellationToken. by @niemyjski in037baae5 - Comprehensive NRT (Nullable Reference Types) null-safety audit: Eliminated
null!suppressions, fixed latent null bugs, and added nullable attributes across the codebase. Return types and parameters may have changed nullability. by @niemyjski in #484, #498
Added
- Upgrade to xUnit v3 with
Foundatio.Xunit.v3: Test infrastructure upgraded to xUnit v3. NewFoundatio.Xunit.v3package with retry test attributes (RetryFactAttribute,RetryTheoryAttribute) for automatic retry of flaky tests. The existingFoundatio.Xunitpackage continues to support xUnit v2. by @niemyjski in #431 - Memory-limited in-memory cache:
InMemoryCacheClientnow supportsMaxMemorySizewith per-entry size limits and intelligent eviction when memory budgets are exceeded. by @niemyjski, @copilot in #400 - Poison message handling for queues and message bus: Deserialization failures in queues and the message bus are now gracefully handled as poison messages instead of crashing consumers. Dead letter logging improved. by @niemyjski in #455
SerializerException: New exception type for serialization-specific errors, enabling targeted error handling. by @niemyjski inb314a052MessageBusException: Consistent error handling for messaging operations with improved delayed message delivery. by @niemyjski in #443QueueDeletedevent onIQueue<T>: Consumers can now subscribe to queue deletion notifications. by @niemyjski in #447- OpenTelemetry error recording: Added
Activity.AddExceptionpolyfill for recording exceptions in distributed traces across all target frameworks. by @niemyjski in #446 - Synchronous
IResiliencePolicymethods: Added sync overloads (Execute,ExecuteAsync) alongside existing async methods. by @ejsmith in #445 - Feature-specific exceptions excluded from resilience policy retries:
QueueException,MessageBusException,StorageException,SerializerException, andCacheExceptionare no longer retried by resilience policies. by @niemyjski in318fa1a0 GetAllExpirationsAsyncandSetAllExpirationsAsynconICacheClient: Bulk expiration read/write support with improved test coverage. by @niemyjski in #426- Option to dispose underlying scoped implementations: Scoped cache/queue/etc. wrappers can now optionally dispose their underlying instances. by @niemyjski in #412
- Job status description:
JobStatusnow supports aDescriptionproperty. by @ejsmith infdcc1442 - Enforce 5ms minimum expiration across all cache implementations: Prevents extremely short TTLs that cause race conditions. by @niemyjski in #463
net10.0target framework: Added .NET 10 support alongside .NET 8. by @niemyjski in [4c6aefed](https://github.c...
v13.0.0-beta6
What's Changed
- fix: implement two-phase dispose for MessageBus subscription lifecycle by @niemyjski in #492
- Add poison message handling for queue deserialization failures by @niemyjski in #455
- Enforce 5ms minimum expiration across all cache implementations by @niemyjski in #463
- Fix InvalidCastException in InMemoryCacheClient.GetAsync<object>() for non-IConvertible types by @Copilot in #468
- Fix race condition in InMemoryQueue.AbandonAsync causing flaky RunUntilEmptyAsync by @niemyjski in #470
- FastCloner as DeepCloner replacement by @lofcz in #469
- Bump dompurify from 3.3.1 to 3.3.2 in /docs by @dependabot[bot] in #471
- Bump rollup from 4.55.1 to 4.59.0 in /docs by @dependabot[bot] in #465
- Bump minimatch from 10.1.1 to 10.2.4 in /docs by @dependabot[bot] in #464
- sync fast cloner to 3.5.3 by @lofcz in #485
- refactor: comprehensive NRT null-safety audit — eliminate null! suppressions, fix latent bugs, add nullable attributes by @niemyjski in #484
- Fix flaky metrics test caused by DateTime.UtcNow timer resolution race by @niemyjski in #488
- Bump lodash-es from 4.17.23 to 4.18.1 in /docs by @dependabot[bot] in #489
- Bump vite from 7.3.1 to 7.3.2 in /docs by @dependabot[bot] in #486
- Bump picomatch from 4.0.3 to 4.0.4 in /docs by @dependabot[bot] in #483
- Document RabbitMQ delayed delivery and plugin deprecation by @niemyjski in #490
New Contributors
Full Changelog: v13.0.0-beta3...v13.0.0-beta6
v13.0.0-beta5
What's Changed
- Add poison message handling for queue deserialization failures by @niemyjski in #455
- Enforce 5ms minimum expiration across all cache implementations by @niemyjski in #463
- Fix InvalidCastException in InMemoryCacheClient.GetAsync<object>() for non-IConvertible types by @Copilot in #468
- Fix race condition in InMemoryQueue.AbandonAsync causing flaky RunUntilEmptyAsync by @niemyjski in #470
- FastCloner as DeepCloner replacement by @lofcz in #469
- Bump dompurify from 3.3.1 to 3.3.2 in /docs by @dependabot[bot] in #471
- Bump rollup from 4.55.1 to 4.59.0 in /docs by @dependabot[bot] in #465
- Bump minimatch from 10.1.1 to 10.2.4 in /docs by @dependabot[bot] in #464
- sync fast cloner to 3.5.3 by @lofcz in #485
- refactor: comprehensive NRT null-safety audit — eliminate null! suppressions, fix latent bugs, add nullable attributes by @niemyjski in #484
- Fix flaky metrics test caused by DateTime.UtcNow timer resolution race by @niemyjski in #488
- Bump lodash-es from 4.17.23 to 4.18.1 in /docs by @dependabot[bot] in #489
- Bump vite from 7.3.1 to 7.3.2 in /docs by @dependabot[bot] in #486
- Bump picomatch from 4.0.3 to 4.0.4 in /docs by @dependabot[bot] in #483
- Document RabbitMQ delayed delivery and plugin deprecation by @niemyjski in #490
New Contributors
Full Changelog: v13.0.0-beta3...v13.0.0-beta5
v13.0.0-beta4
What's Changed
- Add poison message handling for queue deserialization failures by @niemyjski in #455
- Enforce 5ms minimum expiration across all cache implementations by @niemyjski in #463
- Fix InvalidCastException in InMemoryCacheClient.GetAsync<object>() for non-IConvertible types by @Copilot in #468
- Fix race condition in InMemoryQueue.AbandonAsync causing flaky RunUntilEmptyAsync by @niemyjski in #470
- FastCloner as DeepCloner replacement by @lofcz in #469
- Bump dompurify from 3.3.1 to 3.3.2 in /docs by @dependabot[bot] in #471
- Bump rollup from 4.55.1 to 4.59.0 in /docs by @dependabot[bot] in #465
- Bump minimatch from 10.1.1 to 10.2.4 in /docs by @dependabot[bot] in #464
- sync fast cloner to 3.5.3 by @lofcz in #485
- refactor: comprehensive NRT null-safety audit — eliminate null! suppressions, fix latent bugs, add nullable attributes by @niemyjski in #484
- Fix flaky metrics test caused by DateTime.UtcNow timer resolution race by @niemyjski in #488
- Bump lodash-es from 4.17.23 to 4.18.1 in /docs by @dependabot[bot] in #489
- Bump vite from 7.3.1 to 7.3.2 in /docs by @dependabot[bot] in #486
- Bump picomatch from 4.0.3 to 4.0.4 in /docs by @dependabot[bot] in #483
- Document RabbitMQ delayed delivery and plugin deprecation by @niemyjski in #490
New Contributors
Full Changelog: v13.0.0-beta3...v13.0.0-beta4
v13.0.0-beta3
What's Changed
- Fix InMemoryQueue retry: create fresh entry per attempt (entry isolation) by @niemyjski in #454
Full Changelog: v13.0.0-beta2...v13.0.0-beta3
v13.0.0-beta2
What's Changed
- [Breaking]: Normalize ISerializer argument validation and enhance test coverage by @niemyjski in #440
- Improve delayed message delivery and add MessageBusException for consistent error handling by @niemyjski in #443
- Add DeepClone benchmarks, upgrade DeepCloner to v0.10.4, and add sync resilience methods by @niemyjski in #445
- Add QueueDeleted event to IQueue for queue deletion notifications by @niemyjski in #447
- Add QueueException and guard against reusing behavior instances by @niemyjski in #448
- Add OpenTelemetry error recording with Activity.AddException polyfill by @niemyjski in #446
Full Changelog: v13.0.0-beta1...v13.0.0-beta2
v13.0.0-beta1
Breaking Changes
- [Caching]: Normalized
ICacheClient.IncrementAsyncTTL behavior to be consistent across all implementations. #434 by @niemyjski - [Caching]: Removed
ExpiresInargument fromListRemoveAsyncto align with all other Remove methods. #434 by @niemyjski - [Caching]: Ensured consistent return values for
ExpiresInacross all cache operations. #432 by @niemyjski - [Caching]: Removed obsolete
Setmethods from cache extensions. by @niemyjski
Added
- [.NET 10 Support]: Added .NET 10.0 target framework support. by @niemyjski
- [Caching]: Added memory-limited in-memory cache with per-entry size limits and intelligent eviction. #400 by @Copilot
- [Caching]: Added
GetAllExpirationsAsyncandSetAllExpirationsAsyncmethods toICacheClient. #426 by @niemyjski - [Caching]: Added
GetExpirationsAsyncmethod to retrieve cache entry expiration information. by @niemyjski - [Testing]: Added
Foundatio.Xunit.v3package with support for xUnit v3. #431 by @niemyjski - [Caching]: Added scoped cache constructor overload for improved flexibility. by @niemyjski
- [Caching]: Added option to dispose underlying scoped cache implementations. #412 by @niemyjski
- [Locks]: Lock providers now receive dependencies for better integration. by @niemyjski
- [Documentation]: Added comprehensive documentation site with source code links across all features. by @niemyjski @ejsmith
Changed
- [Caching]: Optimized hybrid cache invalidation for improved performance. by @niemyjski
- [Caching]: Improved hybrid cache consistency and double comparison handling. #433 by @niemyjski
- [Caching]: Normalized increment behavior in hybrid cache. by @niemyjski
- [Messaging]: Replaced cancellation token source in
MessageBusBasefor better resource management. by @niemyjski - [Jobs]: Improved
ScheduledTimerdisposal and scheduling. by @niemyjski - [Queues]: Uses
DateTimeOffsetfor queue stats update for better timezone handling. by @niemyjski - [Testing]: Refactored hosting tests to use
HostBuilderdue to deprecations. by @niemyjski - [Testing]: Improved test coverage for caching features. #426 by @niemyjski
- [Build]: Enhanced versioning in build workflow. by @ejsmith
- [Build]: Fixed build workflow publishing empty.nupkg from EmptyFiles test package. #428 by @Copilot
Fixed
- [Caching]: Guards against DateTime overflow in caching operations. by @niemyjski
- [Caching]: Handles zero or negative expiration times correctly. by @niemyjski
- [Cancellation]: Ensures proper disposal of cancellation token sources across all components. by @niemyjski
- [Cancellation]: Ensures tasks are cancelled on disposal. by @niemyjski
- [Cancellation]: Fixed dispose cancellation token usage. by @niemyjski
- [Resilience]: Improved asynchronous timeout handling. by @niemyjski
Dependencies
- Updated to Microsoft.AspNetCore.TestHost 8.0.20 #409
- Updated to BenchmarkDotNet 0.15.3 #410
- Updated to Polly 8.6.3 #406
- Updated to Aspire.Hosting.Redis 9.4.2 #407
- Updated Aspire packages to 9.5.0
- Updated Microsoft package versions
- Updated benchmark dependencies
- Optimized some code for .NET 8
Notes
- This is a beta release. The breaking changes in caching behavior ensure consistency across all implementations and providers.
- .NET 10 support is experimental and subject to change as .NET 10 evolves.
- The new memory-limited cache provides better control over memory usage in high-load scenarios.
- Documentation has been significantly expanded with source code links and implementation details.
v12.0.0
What's Changed
- Storage Exception + FileSpec Data Prop by @niemyjski in #385
- #382 tweak dependencies based on new tfm by @thompson-tomo in #383
- Add extensible resilience policies by @ejsmith in #388
- Adding Foundatio builders for configuring in IServiceCollection. Various other improvements. by @ejsmith in #393
- BREAKING: Improved Cache Tests and normalized ICacheClient.RemoveByPrefix by @niemyjski in #395
- Don't throw immediately if passed in cancellation token is cancelled. by @ejsmith in #397
- Add IHybridAwareCacheClient and Implement Local Cache lookups to HybridCacheClient for GetAllAsync, ExistsAsync, and GetExpirationAsync. by @niemyjski in #401
- Adds queue dequeue activity tracking by @niemyjski in #402
New Contributors
- @thompson-tomo made their first contribution in #383
Full Changelog: v11.1.0...v12.0.0
v11.1.0
What's Changed
- [BREAKING]: Cache Client lists no longer have a sliding expiration and each cache item expires independently by @niemyjski in #376
- Tests for RemoveAllAsync + some tweaks to cache maintenance. by @niemyjski in #377
- Bump MessagePack from 3.1.2 to 3.1.3 by @dependabot in #362
- Bump OpenTelemetry.Instrumentation.Http from 1.11.1 to 1.12.0 by @dependabot in #378
- Bump xunit.runner.visualstudio from 3.0.2 to 3.1.0 by @dependabot in #379
- Bump OpenTelemetry.Instrumentation.AspNetCore from 1.11.1 to 1.12.0 by @dependabot in #380
- Bump OpenTelemetry.Instrumentation.Runtime from 1.11.1 to 1.12.0 by @dependabot in #381
Full Changelog: v11.0.8...v11.1.0