Skip to content

feat: Add support to Polly Resilience Pipeline#3677

Merged
lillo42 merged 27 commits into
BrighterCommand:masterfrom
lillo42:use-polly-resilience-pipeline
Aug 6, 2025
Merged

feat: Add support to Polly Resilience Pipeline#3677
lillo42 merged 27 commits into
BrighterCommand:masterfrom
lillo42:use-polly-resilience-pipeline

Conversation

@lillo42

@lillo42 lillo42 commented Jul 21, 2025

Copy link
Copy Markdown
Contributor

Add support to Polly Resilience Pipeline via a new attribute

  • New attributes (UseResiliencePipelineAttribute and UseResiliencePipelineAsyncAttribute)
  • Changes on IRequestContext to have support to ResiliencePipeline and ResilienceContext
  • Mark TimeoutPolicyAttribute as deprecated

This PR should cover this GH Issues:

#2880
#1197
#1065

@codescene-delta-analysis codescene-delta-analysis Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Gates Failed
Enforce advisory code health rules (1 file with Large Method)

Gates Passed
3 Quality Gates Passed

See analysis details in CodeScene

Reason for failure
Enforce advisory code health rules Violations Code Health Impact
ControlBusReceiverBuilder.cs 1 advisory rule 8.72 → 8.72 Suppress

Quality Gate Profile: Clean Code Collective
Want more control? Customize Code Health rules or catch issues early with our IDE extension and CLI tool.

@codescene-delta-analysis codescene-delta-analysis Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Gates Failed
Enforce advisory code health rules (1 file with Large Method)

Gates Passed
3 Quality Gates Passed

See analysis details in CodeScene

Reason for failure
Enforce advisory code health rules Violations Code Health Impact
ControlBusReceiverBuilder.cs 1 advisory rule 8.72 → 8.72 Suppress

Quality Gate Profile: Clean Code Collective
Want more control? Customize Code Health rules or catch issues early with our IDE extension and CLI tool.

@lillo42 lillo42 marked this pull request as ready for review July 21, 2025 08:54
@lillo42 lillo42 self-assigned this Jul 21, 2025
@lillo42 lillo42 added 3 - Done Breaking Change v10 .NET Pull requests that update .net code labels Jul 21, 2025

@iancooper iancooper left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Thanks for this, it will be great to fix this in V10.

  1. I wonder about having both DefaultPolicy and DefaultResiliencePolicy on the HostBuilder extensions, maybe we just need the new one, and call the old one inside>
  2. I think we should replace our internal uses of Polly with the Resilience Builder. I think that is mainly in OutboxProducerMediator, though it may have crept into some other places. Our internal code should move on, and no one externally depends on that.
  3. We may want to mark UsePolicy as obsolete in the next version; it would be good to clean up and drop it by then.

Comment thread src/Paramore.Brighter/ControlBusSenderFactory.cs Outdated
Comment thread src/Paramore.Brighter.ServiceActivator/ControlBus/ControlBusReceiverBuilder.cs Outdated

@codescene-delta-analysis codescene-delta-analysis Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Code Health Improved (1 files improve in Code Health)

Gates Failed
Prevent hotspot decline (1 hotspot with Large Method)
Enforce advisory code health rules (1 file with Large Method)

Gates Passed
2 Quality Gates Passed

See analysis details in CodeScene

Reason for failure
Prevent hotspot decline Violations Code Health Impact
ControlBusReceiverBuilder.cs 1 rule in this hotspot 8.72 → 8.72 Suppress
Enforce advisory code health rules Violations Code Health Impact
ControlBusReceiverBuilder.cs 1 advisory rule 8.72 → 8.72 Suppress
View Improvements
File Code Health Impact Categories Improved
OutboxProducerMediator.cs 6.95 → 7.16 Deep, Nested Complexity

Quality Gate Profile: Clean Code Collective
Want more control? Customize Code Health rules or catch issues early with our IDE extension and CLI tool.

@slang25 slang25 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.

By complete coincidence, I made a start on a similar change this morning, and then found this PR 😅

I would expect that this change also removes the "old" non-core approach, so the end result would be only a reference to Polly.Core, it would be more of an upgrade burden for folks, but I think it keeps things more simple.

Comment thread src/Paramore.Brighter/Policies/Attributes/UsePolicyAsyncAttribute.cs Outdated
Comment thread src/Paramore.Brighter/Policies/Attributes/UsePolicyAtttribute.cs Outdated
Comment thread src/Paramore.Brighter/Policies/Attributes/UseResiliencePipelineAsyncAttribute.cs Outdated
Comment thread src/Paramore.Brighter/Policies/Handlers/ExceptionPolicyHandlerAsync.cs Outdated
Comment thread src/Paramore.Brighter/Policies/Handlers/ResilienceExceptionPolicyHandler.cs Outdated
Comment thread src/Paramore.Brighter/Policies/Handlers/ResilienceExceptionPolicyHandlerAsync.cs Outdated
@iancooper

Copy link
Copy Markdown
Member

By complete coincidence, I made a start on a similar change this morning, and then found this PR 😅

I would expect that this change also removes the "old" non-core approach, so the end result would be only a reference to Polly.Core, it would be more of an upgrade burden for folks, but I think it keeps things more simple.

As we use an attribute to indicate what Middleware you want, it's easier for us to declare that Obsolete and indicate that we will drop in V11, and then add an attribute for the new Middleware that adopts upgraded Polly policies. That gives folks time to be aware change is coming, and then shift.

I agree that internally to Brighter, though, so not in a middleware pipeline but where the framework uses it for resilience (such as producers etc.) we should move to the new approach. We should only keep the old approach for end users

@codescene-delta-analysis codescene-delta-analysis Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Code Health Improved (1 files improve in Code Health)

Gates Failed
Prevent hotspot decline (2 hotspots with Complex Method, Large Method)
Enforce advisory code health rules (3 files with Complex Method, Large Method, Constructor Over-Injection)

Gates Passed
2 Quality Gates Passed

See analysis details in CodeScene

Reason for failure
Prevent hotspot decline Violations Code Health Impact
ServiceCollectionExtensions.cs 1 rule in this hotspot 9.13 → 9.10 Suppress
ControlBusReceiverBuilder.cs 1 rule in this hotspot 8.72 → 8.70 Suppress
Enforce advisory code health rules Violations Code Health Impact
ServiceCollectionBrighterBuilder.cs 1 advisory rule 9.39 → 9.10 Suppress
ServiceCollectionExtensions.cs 1 advisory rule 9.13 → 9.10 Suppress
ControlBusReceiverBuilder.cs 1 advisory rule 8.72 → 8.70 Suppress
View Improvements
File Code Health Impact Categories Improved
OutboxProducerMediator.cs 6.95 → 7.16 Deep, Nested Complexity

Quality Gate Profile: Clean Code Collective
Want more control? Customize Code Health rules or catch issues early with our IDE extension and CLI tool.

brighterBuilder.Services.TryAddSingleton<IUseRpc>(new UseRpc(busConfiguration.UseRpc, busConfiguration.ReplyQueueSubscriptions!));

brighterBuilder.Services.TryAddSingleton<IAmProducersConfiguration>(busConfiguration);
brighterBuilder.ResiliencePolicyRegistry ??= new ResiliencePipelineRegistry<string>().AddBrighterDefault();

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

❌ Getting worse: Complex Method
AddProducers increases in cyclomatic complexity from 21 to 22, threshold = 9

Suppress

Comment on lines +63 to +64
IPolicyRegistry<string>? policyRegistry = null,
ResiliencePipelineRegistry<string>? resiliencePipelineRegistry = null)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

❌ New issue: Constructor Over-Injection
ServiceCollectionBrighterBuilder has 6 arguments, threshold = 5

Suppress

@codescene-delta-analysis codescene-delta-analysis Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Code Health Improved (1 files improve in Code Health)

Gates Failed
Prevent hotspot decline (2 hotspots with Complex Method, Large Method)
Enforce advisory code health rules (3 files with Complex Method, Large Method, Constructor Over-Injection)

Gates Passed
2 Quality Gates Passed

See analysis details in CodeScene

Reason for failure
Prevent hotspot decline Violations Code Health Impact
ServiceCollectionExtensions.cs 1 rule in this hotspot 9.13 → 9.10 Suppress
ControlBusReceiverBuilder.cs 1 rule in this hotspot 8.72 → 8.70 Suppress
Enforce advisory code health rules Violations Code Health Impact
ServiceCollectionBrighterBuilder.cs 1 advisory rule 9.39 → 9.10 Suppress
ServiceCollectionExtensions.cs 1 advisory rule 9.13 → 9.10 Suppress
ControlBusReceiverBuilder.cs 1 advisory rule 8.72 → 8.70 Suppress
View Improvements
File Code Health Impact Categories Improved
OutboxProducerMediator.cs 6.95 → 7.16 Deep, Nested Complexity

Quality Gate Profile: Clean Code Collective
Want more control? Customize Code Health rules or catch issues early with our IDE extension and CLI tool.

lillo42 added 2 commits July 30, 2025 15:36
# Conflicts:
#	src/Paramore.Brighter/OutboxProducerMediator.cs

@codescene-delta-analysis codescene-delta-analysis Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Gates Failed
Prevent hotspot decline (2 hotspots with Complex Method, Large Method)
Enforce advisory code health rules (3 files with Complex Method, Large Method, Constructor Over-Injection)

Gates Passed
2 Quality Gates Passed

See analysis details in CodeScene

Reason for failure
Prevent hotspot decline Violations Code Health Impact
ServiceCollectionExtensions.cs 1 rule in this hotspot 9.13 → 9.10 Suppress
ControlBusReceiverBuilder.cs 1 rule in this hotspot 8.72 → 8.70 Suppress
Enforce advisory code health rules Violations Code Health Impact
ServiceCollectionBrighterBuilder.cs 1 advisory rule 9.39 → 9.10 Suppress
ServiceCollectionExtensions.cs 1 advisory rule 9.13 → 9.10 Suppress
ControlBusReceiverBuilder.cs 1 advisory rule 8.72 → 8.70 Suppress

Quality Gate Profile: Clean Code Collective
Want more control? Customize Code Health rules or catch issues early with our IDE extension and CLI tool.


var policyRegistry = new PolicyRegistry
{
#pragma warning disable CS0618 // Type or member is obsolete

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

❌ Getting worse: Large Method
Build increases from 76 to 80 lines of code, threshold = 70

Suppress

@codescene-delta-analysis codescene-delta-analysis Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Gates Failed
Prevent hotspot decline (2 hotspots with Complex Method, Large Method)
Enforce advisory code health rules (3 files with Complex Method, Large Method, Constructor Over-Injection)

Gates Passed
2 Quality Gates Passed

See analysis details in CodeScene

Reason for failure
Prevent hotspot decline Violations Code Health Impact
ServiceCollectionExtensions.cs 1 rule in this hotspot 9.13 → 9.10 Suppress
ControlBusReceiverBuilder.cs 1 rule in this hotspot 8.72 → 8.70 Suppress
Enforce advisory code health rules Violations Code Health Impact
ServiceCollectionBrighterBuilder.cs 1 advisory rule 9.39 → 9.10 Suppress
ServiceCollectionExtensions.cs 1 advisory rule 9.13 → 9.10 Suppress
ControlBusReceiverBuilder.cs 1 advisory rule 8.72 → 8.70 Suppress

Quality Gate Profile: Clean Code Collective
Want more control? Customize Code Health rules or catch issues early with our IDE extension and CLI tool.

lillo42 added 3 commits August 5, 2025 11:18
# Conflicts:
#	tests/Paramore.Brighter.Core.Tests/CommandProcessors/Post/When_Posting_A_Message_And_There_Is_No_Message_Transformer.cs
#	tests/Paramore.Brighter.Core.Tests/CommandProcessors/Scheduler/When_Scheduling_A_Message_To_The_Command_Processor_Async.cs
#	tests/Paramore.Brighter.Core.Tests/Observability/CommandProcessor/Clear/When_Clearing_A_Message_A_Span_Is_Exported.cs

@codescene-delta-analysis codescene-delta-analysis Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Gates Failed
Prevent hotspot decline (2 hotspots with Complex Method, Large Method)
Enforce advisory code health rules (3 files with Complex Method, Large Method, Constructor Over-Injection)

Gates Passed
2 Quality Gates Passed

See analysis details in CodeScene

Reason for failure
Prevent hotspot decline Violations Code Health Impact
ServiceCollectionExtensions.cs 1 rule in this hotspot 9.13 → 9.10 Suppress
ControlBusReceiverBuilder.cs 1 rule in this hotspot 8.72 → 8.70 Suppress
Enforce advisory code health rules Violations Code Health Impact
ServiceCollectionBrighterBuilder.cs 1 advisory rule 9.39 → 9.10 Suppress
ServiceCollectionExtensions.cs 1 advisory rule 9.13 → 9.10 Suppress
ControlBusReceiverBuilder.cs 1 advisory rule 8.72 → 8.70 Suppress

Quality Gate Profile: Clean Code Collective
Want more control? Customize Code Health rules or catch issues early with our IDE extension and CLI tool.

@lillo42 lillo42 requested a review from iancooper August 5, 2025 10:50
/// Register that policy with your <see cref="IPolicyRegistry{TKey}"/> such as <see cref="PolicyRegistry"/>
/// You can use this an identifier for you own policies, if your generic policy is the same as your Work Queue policy.
/// </summary>
[Obsolete("Migrate to Resilience Pipeline with OutboxProducer", error: false)]

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Not a problem but I expect we tell users to migrate to the resilience pipeline, and keep our strings for internal usage

Rafael Lillo added 2 commits August 5, 2025 19:25
# Conflicts:
#	src/Paramore.Brighter/OutboxProducerMediator.cs

@codescene-delta-analysis codescene-delta-analysis Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Gates Failed
Prevent hotspot decline (2 hotspots with Complex Method, Large Method)
Enforce advisory code health rules (3 files with Complex Method, Large Method, Constructor Over-Injection)

Gates Passed
2 Quality Gates Passed

See analysis details in CodeScene

Reason for failure
Prevent hotspot decline Violations Code Health Impact
ServiceCollectionExtensions.cs 1 rule in this hotspot 9.13 → 9.10 Suppress
ControlBusReceiverBuilder.cs 1 rule in this hotspot 8.72 → 8.70 Suppress
Enforce advisory code health rules Violations Code Health Impact
ServiceCollectionBrighterBuilder.cs 1 advisory rule 9.39 → 9.10 Suppress
ServiceCollectionExtensions.cs 1 advisory rule 9.13 → 9.10 Suppress
ControlBusReceiverBuilder.cs 1 advisory rule 8.72 → 8.70 Suppress

Quality Gate Profile: Clean Code Collective
Want more control? Customize Code Health rules or catch issues early with our IDE extension and CLI tool.

@lillo42 lillo42 merged commit c536f9a into BrighterCommand:master Aug 6, 2025
23 of 25 checks passed
@lillo42 lillo42 deleted the use-polly-resilience-pipeline branch August 6, 2025 08:14

else
{
await resiliencePipeline.ExecuteAsync(async _ => await send(cancellationToken), cancellationToken)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

You should pass through the cancellation token from the delegate arguments, rather than re-use cancellationToken in the closure, as the token might be different (e.g. combined with a token internal to Polly for handling timeouts).

For example:

await resiliencePipeline.ExecuteAsync(async token => await send(token), cancellationToken)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Thanks @martincostello. @lillo42 one to pick up.

@claude claude Bot mentioned this pull request Oct 25, 2025
DevJonny pushed a commit to DevJonny/Brighter that referenced this pull request Feb 28, 2026
* Add Resilience Pipeline

* fix unit tests

* add unit test

* fix build

* Add more unit tests

* fix build

* feat: Use Resilience Pipeline internally

* fix:  unit tests

* feat: update comment

* feat: Rename register name

* rename method

* fix pipeline and add obsolete attribute

* feat: mark more property as Obsolete and fix unit tests

* fix: build

* Improve outbox producer

* fix: build

* fix: OutboxProducerMediator.cs build
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

3 - Done Breaking Change .NET Pull requests that update .net code

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants