Skip to content
CAI
Software that uses CAICheck a score

App-vNext/Polly

65.2

Weak · 22 September 2026

35.3k

lines of production code

C#

primary language

7

measurements over time

CAI band scale
CAI trend line
CAI lens gauges

What this system is

This system is a .NET resilience and fault-tolerance library that provides a unified API for implementing strategies such as retry, circuit breaking, fallback, hedging, and rate limiting. It supports chaos engineering through the Simmy module, allowing developers to inject faults, latency, and custom behaviors to test system robustness. The library features a modern, non-allocating pipeline architecture with comprehensive telemetry, dynamic configuration reloading, and integration with .NET dependency injection.

How it got here

2013–2023 — Polly V8 resilience pipeline migration

98 changes.

The project underwent a major architectural shift from the legacy V7 policy model to the unified V8 ResiliencePipeline API, introducing a non-allocating, outcome-based design with advanced strategies like hedging and rate limiting. This period involved stripping legacy .NET 3.5/4.0 support, modernizing the build infrastructure with Cake and centralized package management, and implementing comprehensive telemetry and chaos engineering capabilities via the Simmy library.

2024–2025 — Chaos injection utilities and test coverage

4 changes.

This period focused on implementing internal utilities for weighted outcome generation and chaos injection control within the Simmy module. It also expanded test coverage to include new helper classes, registry extension behaviors, and shared infrastructure like strong-naming and cancellation token handling.

Features

Add RateLimit policy for controlling execution throughput

This change introduces a new RateLimit policy capability to Polly, allowing users to restrict the rate at which delegates are executed. The implementation includes synchronous and asynchronous policy classes (\RateLimitPolicy\, \AsyncRateLimitPolicy\) and corresponding fluent syntax extensions (\Policy.RateLimit\, \Policy.RateLimitAsync\) that accept parameters for the number of executions per timespan and a maximum burst size. Internally, it uses a lock-free token-bucket algorithm (\LockFreeTokenBucketRateLimiter\) to manage permits, and throws a new \RateLimitRejectedException\ with a \RetryAfter\ timespan when execution is rejected, enabling callers to handle throttling gracefully.

src/Polly/RateLimit · high confidence

Add dynamic pipeline reloading via options monitoring

Users can now enable automatic reloading of resilience pipelines when configuration options change by calling the new \EnableReloads\ extension method on the builder context. This method accepts an \IOptionsMonitor\ and an optional name to listen for changes in either global or named options, ensuring that updated settings are reflected in the active pipeline without manual intervention.

src/Polly.Extensions/Registry · high confidence

Added PowerShell script and documentation for running benchmarks

A new PowerShell script (benchmarks.ps1) and README have been added to the bench directory to simplify running benchmarks. The script allows users to execute all benchmarks or run them interactively, targeting the .NET 10.0 framework and the Polly.Core.Benchmarks project. Results are stored in the BenchmarkDotNet.Artifacts/results folder.

bench · high confidence

Added source and multiple-sized logo assets

The logos directory now includes the Adobe Illustrator source file (Polly-Logo.ai) and a sticker-specific variant (Polly-Logo Sticker.ai), providing editable source assets alongside the previously available raster formats.

logos · high confidence

Async caching support added to Polly

The \src/Polly/Caching\ area now includes a complete set of new files implementing asynchronous caching capabilities alongside the existing synchronous ones. This includes \AsyncCachePolicy\ and \AsyncCachePolicy\<TResult\>\ for applying caching to async delegates, \AsyncCacheEngine\ for the core async execution logic, and syntax builders in \AsyncCacheSyntax\ and \AsyncCacheTResultSyntax\ to construct these policies. Additionally, new provider implementations like \AsyncSerializingCacheProvider\ and \AsyncGenericCacheProvider\ enable serialization and type-wrapping for async cache stores, while \AbsoluteTtl\ provides absolute time-based expiration strategies.

src/Polly/Caching · high confidence

Introduce Behavior Chaos Strategy for injecting custom actions

Users can now inject custom asynchronous behaviors into resilience pipelines using the new \ChaosBehaviorStrategy\. This feature, located in \Polly.Simmy.Behavior\, allows developers to define a \BehaviorGenerator\ delegate that executes alongside normal operations based on a configurable injection rate. The strategy exposes an \OnBehaviorInjected\ event and telemetry for monitoring when these custom actions are triggered, enabling targeted chaos engineering scenarios that go beyond standard fault injection.

src/Polly.Core/Simmy/Behavior · high confidence

Introduce Chaos Fault injection strategy

Users can now inject faults into resilience pipelines using the new Chaos Fault strategy. This feature adds the \AddChaosFault\ extension method to the pipeline builder, allowing configuration of an injection rate and a fault generator. The implementation includes a \FaultGenerator\ helper class for registering weighted exception types or delegates, and exposes an \OnFaultInjected\ event to notify when a fault is successfully injected into the execution flow.

src/Polly.Core/Simmy/Fault · high confidence

Introduce Chaos Outcome injection strategy

Adds a new Chaos Outcome strategy to the Simmy API, allowing users to intentionally inject specific results or exceptions into their resilience pipelines. This feature includes the \ChaosOutcomeStrategyOptions\ for configuring injection rates and generators, an \OutcomeGenerator\ helper class to easily define weighted exception and result sources, and extension methods on \ResiliencePipelineBuilder\ to wire the strategy into the execution flow.

src/Polly.Core/Simmy/Outcomes · high confidence

Introduce Hedging Resilience Strategy

Adds a new hedging strategy to the resilience pipeline, allowing users to configure automatic retries via additional 'hedged' actions when the primary action is slow or fails. Users can define the maximum number of hedged attempts (default 1, max 10), the delay before spawning a new attempt (default 2 seconds), and custom predicates to determine which outcomes should trigger hedging. The strategy also supports custom delay generators and provides an \OnHedging\ event for telemetry or logging when a hedged action is initiated.

src/Polly.Core/Fallback, src/Polly.Core/Hedging, src/Polly.Core/Timeout · high confidence

Introduce Simmy Chaos Strategy base classes and configuration options

This change introduces the foundational classes for the Simmy chaos engineering library within Polly.Core. It adds the abstract \ChaosStrategy\ and \ChaosStrategy\<T\>\ base classes, which handle the core logic for determining whether chaos should be injected based on configurable rates and enabled states. Alongside these, it provides \ChaosStrategyOptions\ for configuring injection rates, enabled flags, and randomizers, as well as supporting argument structs (\InjectionRateGeneratorArguments\, \EnabledGeneratorArguments\) and constants. This establishes the API surface for defining and running chaos experiments.

src/Polly.Core/Simmy · high confidence

Introduce Timeout Policy with Optimistic and Pessimistic strategies

Users can now apply timeout policies to both synchronous and asynchronous delegates via new \TimeoutPolicy\, \AsyncTimeoutPolicy\, and corresponding extension methods on \Policy\. The implementation supports two enforcement modes: \Optimistic\, which relies on cooperative cancellation via a timing-out \CancellationToken\, and \Pessimistic\, which guarantees the operation is terminated even if the delegate ignores cancellation requests. When a timeout occurs, a \TimeoutRejectedException\ is thrown, and users can provide custom callbacks to handle the timeout event.

src/Polly/Timeout · high confidence

Introduce advanced circuit breaker with configurable failure ratios and throughput thresholds

The circuit breaker controller now supports an advanced mode that trips the circuit based on a configurable failure ratio and minimum throughput requirement, rather than a simple fixed failure count. This is implemented via a new \AdvancedCircuitBehavior\ and a \HealthMetrics\ abstraction that tracks successes and failures over a sliding window (rolling or single, depending on sampling duration). Users benefit from more granular control over when the circuit opens, allowing it to remain closed during low-traffic periods even if the failure rate is high, and to open only when sufficient traffic confirms a systemic issue.

src/Polly.Core/CircuitBreaker/Controller · high confidence

Introduce dedicated NoOp policy implementation

The library now includes a dedicated NoOp policy implementation in the \Polly.NoOp\ namespace, providing \NoOpPolicy\ and \AsyncNoOpPolicy\ classes that execute delegates without any custom behavior. Users can create these policies via the new \Policy.NoOp()\ and \Policy.NoOpAsync()\ extension methods, which return instances of the new \INoOpPolicy\ interface. This change adds explicit support for no-operation scenarios, separating them from general policy logic and enabling nullable reference types within the NoOp implementation.

src/Polly/NoOp · high confidence

Introduces internal utility primitives and pooling infrastructure for resilience strategies

This change adds a suite of internal utility classes in src/Polly.Core/Utils that support the new resilience strategy architecture. It introduces an ObjectPool implementation for efficient resource reuse, a CancellationTokenSourcePool that leverages .NET 8's pooled cancellation sources when available, and a TimeProvider-based DelayAsync helper that respects synchronous execution contexts. Additionally, it provides OutcomeUtilities to correctly propagate caller cancellation tokens in OperationCanceledExceptions, a ValidationHelper for options validation, and various helper classes for exception handling, type formatting, and argument guarding.

src/Polly.Core/Utils · high confidence

New Chaos Latency strategy for injecting artificial delays

The Simmy latency chaos module now includes a new \ChaosLatencyStrategy\ that allows you to intentionally introduce delays into your resilience pipeline. Users can configure the injection rate and a fixed latency duration (defaulting to 30 seconds) or provide a custom generator for dynamic delays. The strategy exposes an \OnLatencyInjected\ event and telemetry reporting, enabling you to monitor and react when artificial latency is applied to your operations.

src/Polly.Core/Simmy/Latency · high confidence

New DI context enables dynamic reloads and disposal hooks for resilience pipelines

The dependency injection registration API now passes an \AddResiliencePipelineContext\ to the configuration callback, giving users access to the service provider and the ability to call \EnableReloads\ (or \EnableReloadsWithMonitor\) so that a pipeline automatically rebuilds when its associated \IOptionsMonitor\ changes. The context also exposes \GetOptions\ for reading named or global options and \OnPipelineDisposed\ to register cleanup callbacks when the pipeline instance is disposed.

src/Polly.Extensions/DependencyInjection · high confidence

New Polly.Testing package for pipeline introspection

Introduces the \Polly.Testing\ package, providing APIs to inspect the composition of resilience pipelines. Users can now call \GetPipelineDescriptor()\ on a \ResiliencePipeline\ to retrieve a \ResiliencePipelineDescriptor\, which exposes the list of strategies (\Strategies\), the first strategy (\FirstStrategy\), and whether the pipeline is reloadable (\IsReloadable\). Each strategy in the list is described by a \ResilienceStrategyDescriptor\ containing its options and instance, enabling assertions on pipeline structure and configuration in tests.

src/Polly.Testing · high confidence

New advanced circuit breaker with configurable failure thresholds and throughput

Users can now define circuit breakers that break based on a failure ratio within a sliding time window rather than a fixed count of consecutive failures. The new \AdvancedCircuitBreaker\ and \AdvancedCircuitBreakerAsync\ syntax methods accept \failureThreshold\, \samplingDuration\, and \minimumThroughput\ parameters, allowing the circuit to open only when the proportion of failures exceeds the threshold during the sampling period and sufficient traffic has passed. This location provides the fluent API syntax (\AdvancedCircuitBreakerSyntax\, \AdvancedCircuitBreakerTResultSyntax\, \AsyncAdvancedCircuitBreakerSyntax\) and the underlying \AdvancedCircuitController\ that implements the health metrics and state transitions for this behavior.

src/Polly/CircuitBreaker · high confidence

New rate-limiting strategy for ResiliencePipelineBuilder

The \Polly.RateLimiting\ package now provides a rate-limiting strategy that integrates with the .NET \System.Threading.RateLimiting\ APIs. Users can add rate limiting to their resilience pipelines via \ResiliencePipelineBuilder.AddRateLimiter\ (accepting a custom \RateLimiter\ or \RateLimiterStrategyOptions\) or the convenience \AddConcurrencyLimiter\ method. The strategy exposes \RateLimiterRejectedException\ with a \RetryAfter\ property, supports an \OnRejected\ callback for custom handling of rejected executions, and includes telemetry reporting for rejection events.

src/Polly.RateLimiting · high confidence

New resilience telemetry API for monitoring pipeline execution

The telemetry subsystem in src/Polly.Core/Telemetry has been replaced with a new event-based system. Users can now subscribe to resilience events via the abstract TelemetryListener class, which receives structured data through TelemetryEventArguments. The new API introduces specific argument types for different lifecycle stages, including ExecutionAttemptArguments (providing attempt number, duration, and handling status), PipelineExecutingArguments, and PipelineExecutedArguments. Events are categorized by severity using the new ResilienceEventSeverity enum (ranging from Debug to Critical) and are reported by strategies through ResilienceStrategyTelemetry. The source of each event is identified by ResilienceTelemetrySource, which includes the pipeline name, instance name, and strategy name, allowing for precise tracking of resilience behavior.

src/Polly.Core/Telemetry · high confidence

New samples for chaos engineering and custom strategy extensibility

The samples directory now includes a Chaos example demonstrating how to inject faults, latency, and outcomes into HTTP client calls using Polly.Simmy strategies, controlled via a configurable IChaosManager. Additionally, new Extensibility samples show how to implement custom proactive and reactive resilience strategies, including defining options, strategies, and builder extensions for scenarios like timing thresholds and result reporting.

samples · high confidence

New telemetry infrastructure for resilience pipelines

The \src/Polly.Extensions/Telemetry\ directory now provides the core implementation for resilience telemetry, enabling pipelines to log and meter execution events. This includes a new \TelemetryOptions\ configuration class, a \TelemetryListenerImpl\ that emits structured logs via \ILogger\ and metrics via \System.Diagnostics.Metrics\ (counters for events, histograms for attempt and execution durations), and a \MeteringEnricher\ system allowing users to attach custom tags to these metrics. The implementation introduces specific telemetry tags (such as \event.name\, \pipeline.name\, \strategy.name\, and \operation.key\) and supports customizing event severity through a \SeverityProvider\.

src/Polly.Extensions/Telemetry · high confidence

PolicyRegistry now supports safe concurrent add, remove, and update operations

The PolicyRegistry in src/Polly/Registry has been refactored to expose a richer set of thread-safe methods for managing policies. Users can now use TryAdd and TryRemove to safely add or remove policies without throwing exceptions on conflicts or missing keys, and TryUpdate allows conditional replacement of a policy if it matches a specific value. Additionally, GetOrAdd and AddOrUpdate methods provide atomic operations to retrieve an existing policy or create/update one based on whether the key is present, simplifying common registry manipulation patterns in concurrent scenarios.

src/Polly/Registry · high confidence

Polly V8 introduces a unified, non-allocating resilience API

Polly V8 replaces the previous policy interfaces with a unified \ResiliencePipeline\ that handles synchronous and asynchronous execution via a single API surface. The library now uses an \Outcome\ struct to represent both successful results and exceptions, allowing strategies to handle failures without throwing. A new \PredicateBuilder\ enables fluent configuration of retry, fallback, circuit breaker, and hedging strategies, while a \ResilienceContextPool\ manages execution context instances to reduce allocations. The \ExecutionRejectedException\ now includes a \TelemetrySource\ property for better debugging, and \ResilienceProperties\ support is added for attaching custom data to executions.

src/Polly.Core · high confidence

Removals

Removal of SystemClock utility class

The SystemClock utility class, which previously provided static delegates for time-related operations like Thread.Sleep and DateTime.UtcNow to improve testability, has been removed from the codebase. This change eliminates the ability to inject custom sleep or time implementations for testing purposes within this specific component.

src/Polly.Net35/Utilities · high confidence

Removal of legacy .NET 3.5 circuit breaker implementation

The legacy circuit breaker components for .NET 3.5 have been removed from the codebase. This change deletes the \BrokenCircuitException\ class, the internal \CircuitBreakerPolicy\ and \CircuitBreakerState\ implementations, and the \ICircuitBreakerState\ interface. Users targeting .NET 3.5 will no longer have access to the circuit breaker pattern in this library version.

src/Polly.Net35/CircuitBreaker · high confidence

Removal of legacy .NET 3.5 policy implementation files

The core policy implementation files for the .NET 3.5 target have been removed from the \src/Polly.Net35\ directory. This includes the deletion of \Policy.cs\, \PolicyBuilder.cs\, and the fluent API syntax files \CircuitBreakerSyntax.cs\, \OrSyntax.cs\, and \RetrySyntax.cs\. This change eliminates the synchronous policy execution logic and exception-handling syntax definitions that were specific to the older framework version, aligning with the project's shift to focus on .NET 4.0+ and asynchronous patterns.

src/Polly.Net35 · high confidence

Architecture

New centralized build and release engineering infrastructure

The \eng\ directory now contains a comprehensive set of MSBuild targets and PowerShell scripts that standardize the build, analysis, and release processes. This includes centralized configuration for code analyzers (StyleCop, SonarAnalyzer, Banned API, Public API), benchmarking (BenchmarkDotNet), and testing (xUnit v3, Microsoft Testing Platform, code coverage). It also introduces automation for version bumping, changelog updates, and public API baseline management, alongside deterministic build settings and NuGet package validation.

eng · high confidence

Repository infrastructure modernized with .slnx, Cake build, and developer guidelines

The repository has been restructured to support modern .NET development workflows. The legacy .sln file and associated assembly info files have been replaced with a new .slnx solution format and centralized MSBuild props/targets. A Cake-based build system (cake.cs) now orchestrates builds, tests, and coverage, replacing previous methods. New documentation files including AGENTS.md (coding agent instructions), CONTRIBUTING.md, SECURITY.md, and CODE\_OF\_CONDUCT.md provide clear guidelines for contributors and automated agents. The license has been updated from New BSD to BSD 3-Clause, and various configuration files (.editorconfig, .gitattributes, .markdownlint.json, mdsnippets.json) have been added to enforce code quality and consistency.

(repo-wide) · high confidence

Behavioural changes

Added circuit breaker health tracking data structure

A new internal HealthInfo record struct has been introduced to track circuit breaker health metrics, specifically calculating throughput, failure rate, and failure count based on success and failure inputs.

Polly.Core · high confidence

Added legacy support attributes for trimming and nullability

The src/LegacySupport directory now includes polyfill implementations for .NET trimming and nullability attributes, including CallerArgumentExpressionAttribute, DynamicDependencyAttribute, DynamicallyAccessedMembersAttribute, DynamicallyAccessedMemberTypes, IsExternalInit, NullableAttributes (such as AllowNull, DisallowNull, MaybeNull, NotNull, and their When/IfNotNull variants), RequiresUnreferencedCodeAttribute, and UnconditionalSuppressMessageAttribute. These additions enable the library to support C\# 9/10 records on older frameworks and provide the necessary metadata for trimming tools to understand dynamic dependencies and nullability contracts, ensuring compatibility and correct analysis when building for trimmed or older .NET targets.

src/LegacySupport · high confidence

AssemblyInfo.cs introduces type forwarding for core exceptions and enums

The newly created AssemblyInfo.cs file in src/Polly/Properties now explicitly forwards types ExecutionRejectedException, TimeoutRejectedException, BrokenCircuitException, IsolatedCircuitException, and CircuitState. This change ensures that consumers of the Polly package can access these specific types without needing to reference the underlying core assembly directly, maintaining API compatibility while the library structure shifts to reference Polly.Core.

src/Polly/Properties · high confidence

Async policy execution API restructured with new overloads and context support

The \AsyncPolicy\ and \AsyncPolicy\<TResult\>\ classes have been refactored to expose a comprehensive set of \ExecuteAsync\ and \ExecuteAndCaptureAsync\ overloads. These methods now accept \Context\ objects, \IDictionary\ context data, \CancellationToken\ parameters, and a \continueOnCapturedContext\ boolean, allowing users to control execution context, cancellation, and synchronization behavior. The \Context\ class itself has been expanded to include \PolicyKey\, \PolicyWrapKey\, and \CorrelationId\ properties for better tracking and logging. Additionally, a \WithPolicyKey\ method has been added to both policy types to allow assigning unique identifiers to policy instances before execution.

src/Polly · high confidence

Benchmarks updated to support Polly v8 ResiliencePipeline API

The benchmark utility helpers in \bench/Polly.Core.Benchmarks/Utils\ have been rewritten to support the new Polly v8 API surface alongside the legacy v7 API. This includes introducing \EmptyResilienceOptions\ and \EmptyResilienceStrategy\ for baseline comparisons, adding \Outcome\-aware handling in circuit breaker and retry strategies, and migrating execution paths to use \ResiliencePipeline\ and \ResilienceContextPool\ instead of the older \IAsyncPolicy\ model. New helper methods cover hedging, rate limiting (via \ConcurrencyLimiter\), and telemetry configuration, ensuring benchmarks can accurately measure performance differences between the v7 and v8 resilience implementations.

bench/Polly.Core.Benchmarks/Utils · high confidence

Bulkhead policy implementation refactored to use separate semaphores for parallelization and queuing

The bulkhead isolation policy in src/Polly/Bulkhead has been restructured to introduce a dedicated queuing mechanism. Instead of limiting only concurrent executions, the policy now accepts a maxQueuingActions parameter, allowing actions to wait in a queue when the parallelization limit is reached. This is implemented via a new BulkheadSemaphoreFactory that creates two distinct SemaphoreSlim instances—one for parallel execution slots and one for the queue—and updated BulkheadPolicy and AsyncBulkheadPolicy classes that expose BulkheadAvailableCount and QueueAvailableCount properties to monitor both limits.

src/Polly/Bulkhead · high confidence

Circuit breaker strategy now exposes manual control, state monitoring, and detailed lifecycle events

The circuit breaker implementation has been refactored to provide finer-grained control and observability. Users can now manually isolate or reset the circuit using the new \CircuitBreakerManualControl\ class, which supports reuse across multiple breakers and allows initialization in an isolated state. The \CircuitBreakerStateProvider\ enables real-time monitoring of the circuit's state (Closed, Open, HalfOpen, or Isolated). Additionally, the strategy now exposes lifecycle events (\OnOpened\, \OnClosed\, \OnHalfOpened\) via dedicated argument structs that include context, outcome, and flags indicating whether the transition was manual. The \BrokenCircuitException\ now includes a \RetryAfter\ property to indicate when the circuit will close, and the \BreakDurationGeneratorArguments\ now includes \HalfOpenAttempts\ to support dynamic break duration logic based on half-open trial results.

src/Polly.Core/CircuitBreaker · high confidence

Enforce modern time APIs and stricter code analysis rules

The build system now enforces stricter code quality and style rules across the project. Developers are required to use \TimeProvider.GetLocalNow()\ instead of \DateTime.Now\, \DateTime.Today\, \DateTimeOffset.Now\, or \DateTimeOffset.Today\ to improve time-handling consistency. Additionally, implicit casting from \DateTime\ to \DateTimeOffset\ is now banned. The \eng/analyzers\ directory introduces new configuration files (\BannedSymbols.txt\, \Benchmark.globalconfig\, \Library.globalconfig\, \SonarLint.xml\, \Stylecop.globalconfig\, \Stylecop.json\, \Test.globalconfig\) that standardize diagnostic severities, enforce specific coding styles (such as expression-bodied members and null propagation), and configure SonarLint rules, ensuring a uniform codebase standard.

eng/analyzers · high confidence

Fallback policy implementation refactored into dedicated engine and syntax classes

The Fallback policy logic in src/Polly/Fallback has been restructured to improve code organization and maintainability. The core execution logic is now encapsulated in dedicated engine classes (AsyncFallbackEngine and FallbackEngine), which handle the actual execution, exception handling, and fallback invocation. The policy classes (AsyncFallbackPolicy, FallbackPolicy, and their generic variants) now delegate to these engines, providing a cleaner separation of concerns. Additionally, the fluent API syntax has been reorganized into separate static classes (AsyncFallbackSyntax, FallbackSyntax, AsyncFallbackTResultSyntax, FallbackTResultSyntax) for better discoverability and to reduce coupling between the policy implementation and the builder API. This change also introduces explicit null checks for action parameters in the policy implementations, enhancing robustness against null reference exceptions.

src/Polly/Fallback · high confidence

Introduce internal hedging execution controller and context management

The hedging strategy now uses a new internal controller architecture (HedgingController, HedgingExecutionContext, TaskExecution) to manage primary and secondary task lifecycles. This change introduces object pooling for execution contexts and tasks to reduce allocation overhead, adds an AttemptNumber to track hedging attempts, and ensures that cancellation tokens and resources are properly pooled and disposed. Users benefit from improved performance and resource efficiency when using the hedging resilience strategy, with no changes to the public API.

src/Polly.Core/Hedging/Controller · high confidence

Introduces internal utilities for weighted outcome generation and chaos injection control

Added two new internal helper classes to the Simmy utilities: \ChaosStrategyHelper\ and \GeneratorHelper\. \ChaosStrategyHelper\ provides logic to determine whether a chaos injection should occur by evaluating enabled and injection-rate generators against a randomizer, while enforcing cancellation checks and coercing thresholds to valid bounds. \GeneratorHelper\ implements a weighted random selection mechanism, allowing multiple outcome generators to be registered with specific weights so that outcomes are selected probabilistically based on those weights.

src/Polly.Core/Simmy/Utils · high confidence

Refactored PolicyWrap into modular components with explicit context key handling

The PolicyWrap implementation in src/Polly/Wrap has been restructured into distinct files for the core wrap classes (AsyncPolicyWrap, PolicyWrap), their execution engines (AsyncPolicyWrapEngine, PolicyWrapEngine), and extension methods for both sync and async policies. A key behavioral addition is the new SetPolicyContext method in PolicyWrap and AsyncPolicyWrap, which now explicitly manages and preserves Context.PolicyWrapKey and Context.PolicyKey during execution, ensuring that context keys are correctly tracked when policies are nested. This change improves the clarity and maintainability of the wrap logic while ensuring accurate context propagation for wrapped policy executions.

src/Polly/Wrap · high confidence

Refactored Utilities with modern C\# patterns and improved testability

The Utilities folder has been modernized to use file-scoped namespaces, nullable reference types, and expression-bodied members. A new SystemClock class was added to provide injectable delegates for time-related operations (such as Sleep, UtcNow, and CancelTokenAfter), significantly improving the testability of Polly's timing logic. Additionally, the TimedLock struct was migrated from the legacy Net35 folder, updated to use readonly struct semantics, and enhanced with a configurable lock timeout that distinguishes between Debug and Release builds to aid in deadlock detection during development without impacting production performance.

src/Polly/Utilities · high confidence

Refactored resilience pipeline execution and disposal internals

The internal pipeline execution engine has been restructured into a chain of dedicated components (Bridge, Delegating, Composite, ExecutionTracking, and Reloadable) to improve performance and support AOT compilation. This change introduces a new disposal model where the pipeline explicitly manages the lifecycle of its internal strategies while ensuring that external components (such as those provided by the user or from other pipelines) are not disposed when the pipeline itself is disposed. Additionally, reloadable pipelines now safely handle component replacement and disposal, reporting telemetry for reload and disposal failures.

src/Polly.Core/Utils/Pipeline · high confidence

Removal of .NET 3.5 Assembly Metadata

The AssemblyInfo.cs file for the .NET 3.5 target has been deleted, removing the AssemblyTitle attribute definition for that specific framework version. This change aligns with the removal of the .NET 3.5 target from the project, meaning the library no longer produces or maintains assembly metadata for that legacy framework.

src/Polly.Net35/Properties · high confidence

Removal of Polly.Net40 AssemblyInfo file

The AssemblyInfo.cs file in the Polly.Net40 project has been deleted. This change removes the explicit assembly metadata (such as the title) that was previously defined in this file, likely as part of a broader effort to simplify the project structure or migrate to a different assembly configuration method.

src/Polly.Net40, src/Polly.Net45 · medium confidence

Removal of internal retry policy state management classes

The internal implementation details for retry policy state tracking have been removed from the codebase. Specifically, the \IRetryPolicyState\ interface and its concrete implementations (\RetryPolicyStateWithCount\ and \RetryPolicyStateWithSleep\) along with the \RetryPolicy\ helper class have been deleted. This change eliminates the internal mechanism that previously managed retry counts, sleep durations, and on-retry callbacks for the retry policy.

src/Polly.Net35/Retry · high confidence

Removal of legacy NuGet package restore infrastructure

The project has removed the \.nuget\ directory, specifically deleting \NuGet.Config\ and \NuGet.targets\. This eliminates the custom MSBuild targets that previously handled downloading \nuget.exe\ and restoring packages via \packages.config\. Users will no longer rely on this legacy, commit-based package restore mechanism, implying a shift to a different package management approach (such as \PackageReference\ or built-in NuGet restore).

.nuget · high confidence

ResiliencePipelineRegistry now supports dynamic pipeline reloading and proper disposal

The ResiliencePipelineRegistry in src/Polly.Core/Registry has been refactored to support dynamic reloads and improved resource management. Users can now register cancellation tokens via ConfigureBuilderContext.AddReloadToken to trigger automatic pipeline recreation when configuration changes, and the registry itself implements IDisposable/IAsyncDisposable to ensure linked resources are cleaned up when the registry is disposed.

src/Polly.Core/Registry · high confidence

Retry strategy now uses Outcome-based arguments and exposes jitter for all backoff types

The retry strategy in src/Polly.Core/Retry has been refactored to pass Outcome-based arguments (OnRetryArguments, RetryPredicateArguments, RetryDelayGeneratorArguments) to its configuration callbacks, giving users access to the attempt number, outcome, and execution duration. The default backoff type has changed from Exponential to Constant, and jitter is now supported for all backoff types (Constant, Linear, and Exponential) via the new UseJitter option. Additionally, a MaxDelay property allows capping the retry delay, and the strategy now safely handles delay overflows and disposes of discarded results after a retry.

src/Polly.Core/Retry · high confidence

V7-to-V8 bridge implementation for ResiliencePipeline

This change introduces internal wrapper classes (ResiliencePipelineAsyncPolicy, ResiliencePipelineSyncPolicy, and their generic variants) that allow existing Polly V7 AsyncPolicy and Policy implementations to execute against the new V8 ResiliencePipeline. These wrappers act as a bridge, converting the legacy Context into the new ResilienceContext using a new ResilienceContextFactory and pool, ensuring that properties are correctly transferred and cleaned up after execution. This enables users to gradually migrate from the V7 policy model to the V8 pipeline model without rewriting all their resilience logic at once.

src/Polly/Utilities/Wrappers · high confidence

Fixes

Async retry policies now respect the ContinueOnCapturedContext configuration

The async retry implementation in \AsyncRetryEngine\ has been updated to pass the \continueOnCapturedContext\ flag to all \ConfigureAwait\ calls. This ensures that retry callbacks and the underlying action execute on the correct synchronization context when configured, fixing a bug where the context was previously ignored.

src/Polly/Retry · high confidence

Test coverage

Add Polly policy benchmarks; Add Polly v8 benchmark suite; Added AOT compilation test entry point; Added comprehensive unit tests for Bulkhead policy configuration and behavior; Added comprehensive unit tests for Circuit Breaker policies; Added comprehensive unit tests for Fallback policy variants; Added comprehensive unit tests for Polly Timeout policies; Added issue regression tests for Polly.Extensions scenarios; Added regression tests for Polly.Core resilience strategies; Added strong-naming and cancellation token tests; Added test helper utilities for controlled exception and result sequencing; Added test helpers for caching strategy and serialization; Added test helpers for custom policy behaviors; Added test helpers for deterministic bulkhead policy testing; Added test helpers for rate limiter assertions; Added tests for Chaos Latency strategy and related components; Added tests for Circuit Breaker Controller components; Added tests for PolicyWrap extension methods and context/key propagation; Added tests for Resilience Pipeline DI registration; Added tests for ResiliencePipeline descriptor inspection; Added tests for Simmy Chaos Behavior strategy components; Added tests for Simmy Chaos Fault strategy and supporting components; Added tests for Simmy Chaos Outcome strategy; Added tests for Simmy Chaos Strategy; Added tests for circuit breaker arguments, options, and state management; Added tests for pipeline disposal and reloadable strategy behavior; Added tests for rate-limiting resilience strategy integration; Added tests for the Timeout resilience strategy; Added unit tests for ConfigureBuilderContextExtensions; Added unit tests for LockTimeoutException and SystemClock utilities; Added unit tests for NoOp policy variants; Added unit tests for PolicyRegistry operations; Added unit tests for Polly Retry policies; Added unit tests for Polly caching components; Added unit tests for Polly.Core utility classes; Added unit tests for TelemetryUtil helper methods; Added unit tests for core resilience primitives; Added unit tests for core telemetry components; Added unit tests for hedging controller internals; Added unit tests for pipeline component lifecycle and disposal; Added unit tests for rate-limiting policies and token bucket implementation; Added unit tests for telemetry implementation details; Added unit tests for the Fallback resilience strategy; Added unit tests for the Hedging strategy; Added unit tests for the ResiliencePipelineRegistry and related components; Added unit tests for the retry strategy implementation; Expanded test utilities for telemetry, logging, and resilience strategies; Expanded unit test coverage for core Polly execution and context behaviors; Removed legacy synchronous test suite in src/Polly.Specs; Removed test helper for raising exceptions in policies.

Dependencies

Adopts Central Package Management and modernizes .NET targets

The project now uses a centralized \Directory.Packages.props\ file to manage dependency versions, replacing the legacy \packages.config\ and individual version pins. This change consolidates the dependency graph, updating key packages such as xunit to v3, NSubstitute to v6, and Refit to v15. Additionally, the build targets have been modernized: old .NET Framework projects (Net35, Net40, Net45) have been removed, and new samples and benchmarks now target .NET 8, 9, and 10, with the core library supporting .NET 6, 8, and standard profiles.

(dependencies) · high confidence

Written by watchdog.canine.dev from the codebase's own history, inside the signed delivery this page is composed from.

How this codebase got here

Score

  • CAI 58 → 65 (+7.2)
  • Rubric changed (rubric-2026.08.19 → rubric-2026.09.15) — scores are not directly comparable.

Lenses

  • Code Health 40 → 52 (+12.4)
  • Architecture 95 → 95 (+0.2)
  • Maturity 70 → 73 (+3.6)
  • Readiness 68 → 74 (+5.9)
  • Security 97 → 96 (-0.5)
  • Performance 83 → 76 (-6.5)

Resolved (112)

  • BarePragmaDisable (src/LegacySupport/CallerArgumentExpressionAttribute.cs)
  • BarePragmaDisable (src/LegacySupport/CallerArgumentExpressionAttribute.cs)
  • BarePragmaDisable (src/LegacySupport/CallerArgumentExpressionAttribute.cs)
  • BarePragmaDisable (src/LegacySupport/DynamicDependencyAttribute.cs)
  • BarePragmaDisable (src/LegacySupport/DynamicDependencyAttribute.cs)
  • BarePragmaDisable (src/LegacySupport/DynamicDependencyAttribute.cs)
  • BarePragmaDisable (src/LegacySupport/DynamicDependencyAttribute.cs)
  • BarePragmaDisable (src/LegacySupport/DynamicDependencyAttribute.cs)
  • BarePragmaDisable (src/LegacySupport/DynamicDependencyAttribute.cs)
  • BarePragmaDisable (src/LegacySupport/DynamicDependencyAttribute.cs)
  • BarePragmaDisable (src/LegacySupport/DynamicallyAccessedMemberTypes.cs)
  • BarePragmaDisable (src/LegacySupport/DynamicallyAccessedMemberTypes.cs)
  • BarePragmaDisable (src/LegacySupport/DynamicallyAccessedMemberTypes.cs)
  • BarePragmaDisable (src/LegacySupport/DynamicallyAccessedMemberTypes.cs)
  • BarePragmaDisable (src/LegacySupport/DynamicallyAccessedMembersAttribute.cs)
  • BarePragmaDisable (src/LegacySupport/DynamicallyAccessedMembersAttribute.cs)
  • BarePragmaDisable (src/LegacySupport/DynamicallyAccessedMembersAttribute.cs)
  • BarePragmaDisable (src/LegacySupport/DynamicallyAccessedMembersAttribute.cs)
  • BarePragmaDisable (src/LegacySupport/DynamicallyAccessedMembersAttribute.cs)
  • BarePragmaDisable (src/LegacySupport/DynamicallyAccessedMembersAttribute.cs)
  • …and 92 more

New (167)

  • AnalyzerSeverityNone (.editorconfig)
  • AnalyzerSeverityNone (.editorconfig)
  • AnalyzerSeverityNone (test/.editorconfig)
  • AnalyzerSeverityNone (test/.editorconfig)
  • AnalyzerSeverityNone (test/.editorconfig)
  • AnalyzerSeverityNone (test/Polly.Specs/.editorconfig)
  • AnalyzerSeverityNone (test/Polly.Specs/.editorconfig)
  • AnalyzerSeverityNone (test/Polly.Specs/.editorconfig)
  • AnalyzerSeverityNone (test/Polly.Specs/.editorconfig)
  • AnalyzerSeverityNone (test/Polly.Specs/.editorconfig)
  • BarePragmaDisable (src/Polly.Core/CircuitBreaker/Controller/CircuitStateController.cs)
  • BarePragmaDisable (src/Polly.Core/CircuitBreaker/Controller/CircuitStateController.cs)
  • BarePragmaDisable (src/Polly.Core/CircuitBreaker/Controller/CircuitStateController.cs)
  • BarePragmaDisable (src/Polly.Core/Utils/RandomUtil.cs)
  • BarePragmaDisable (test/Polly.Extensions.Tests/Issues/IssuesTests.PartitionedRateLimiter_1365.cs)
  • Change coupling: AsyncRetryTResultSyntax.cs ↔ RetrySyntax.cs (src/Polly/Retry/AsyncRetryTResultSyntax.cs)
  • CoverageExclusion (src/LegacySupport/CallerArgumentExpressionAttribute.cs)
  • CoverageExclusion (src/LegacySupport/DynamicDependencyAttribute.cs)
  • CoverageExclusion (src/LegacySupport/DynamicallyAccessedMembersAttribute.cs)
  • CoverageExclusion (src/LegacySupport/NullableAttributes.cs)
  • …and 147 more

Changes since last survey

  • 51 commits — 49 feature/other, 2 fixes

By area

  • (root) — 19 commits
  • .github/workflows — 17 commits
  • .config/dotnet-tools.json — 8 commits
  • src/Polly.Core — 4 commits
  • test/Polly.Specs — 2 commits
  • docs/strategies — 1 commit

Notable commits

  • fix: Fix XML doc comment (#3201)
  • fix: Fix flaky test (#3231)
  • change: .NET 11 preparation (#3225)
  • change: Bump Cake.Sdk from 6.2.0 to 6.3.0 (#3237)
  • change: Bump DavidAnson/markdownlint-cli2-action from 24.1.0 to 24.2.0 (#3195)
  • change: Bump FsCheck.Xunit from 3.3.4 to 3.4.0 (#3210)
  • change: Bump Microsoft.NET.Test.Sdk from 18.8.1 to 18.9.0 (#3206)
  • change: Bump MinVer from 7.0.0 to 8.0.0 (#3224)
  • change: Bump NSubstitute from 6.0.0 to 6.2.0 (#3198)
  • change: Bump Refit.HttpClientFactory from 14.0.1 to 15.0.0 (#3199)
  • change: Bump Refit.HttpClientFactory from 15.0.0 to 15.2.0 (#3207)
  • change: Bump SonarAnalyzer.CSharp from 10.29.0.143774 to 10.31.0.145097 (#3190)
  • change: Bump SonarAnalyzer.CSharp from 10.31.0.145097 to 10.32.0.713 (#3200)
  • change: Bump SonarAnalyzer.CSharp from 10.32.0.713 to 10.33.0.1635 (#3212)
  • change: Bump SonarAnalyzer.CSharp from 10.33.0.1635 to 10.34.0.3385 (#3230)
  • change: Bump actions/attest from 4.2.0 to 4.2.2 (#3188)
  • change: Bump anchore/sbom-action from 0.24.0 to 0.24.2 (#3216)
  • change: Bump azure/login from 3.0.0 to 3.0.1 (#3187)
  • change: Bump azure/login from 3.0.1 to 3.0.2 (#3215)
  • change: Bump azure/login from 3.0.2 to 3.1.0 (#3233)
  • …and 31 more

API surface

  • Unchanged — 1 HTTP endpoints

Architecture

  • Unchanged — 7 containers · 1 contexts · 0 edges

Written by watchdog.canine.dev from the codebase's own history, inside the signed delivery this page is composed from.

Survey your own repository

App-vNext/Polly was measured the same way every project in this corpus was: the same rubric, at a pinned commit, with the result published in full. Point a surveyor at a repository you know and see whether you agree with it.

About this page

  • The score is its most recent published measurement, taken on 22 September 2026 at a pinned commit. It is not a live figure and does not change until the project is measured again.
  • Measured at commit 9a81fdc7c1a89d6c45bba2fb7b062b8eeae39eee — the exact code this score is about.
  • Scored under rubric-2026.09.15 — the same rubric and the same method as every other entry in this index.
  • Measured by watchdog.canine.dev using codehealth-analyzer preprod-821afab8930d.