diff --git a/.github/ISSUE_TEMPLATE/bug-.md b/.github/ISSUE_TEMPLATE/bug-.md deleted file mode 100644 index f32e614158d..00000000000 --- a/.github/ISSUE_TEMPLATE/bug-.md +++ /dev/null @@ -1,18 +0,0 @@ ---- -name: Bug? -about: "... or something not behaving as expected?" ---- - -**Summary**: - -**Expected behavior**: - - -**Actual behaviour**: - -**Steps / Code to reproduce the problem**: - -Best is a [complete example](https://stackoverflow.com/help/mcve) or failing unit test. It is _always_ useful to see: - -+ **code of any policy declarations**, -+ **code of calls to `.Execute/AndCapture/Async(...)`** diff --git a/.github/ISSUE_TEMPLATE/bug.md b/.github/ISSUE_TEMPLATE/bug.md new file mode 100644 index 00000000000..26b6d107afd --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug.md @@ -0,0 +1,16 @@ +--- +name: Bug? +about: "... or something not behaving as expected?" +--- + +# Bug Report + +## Summary + +## Expected behavior + +## Actual behaviour + +## Steps / Code to reproduce the problem + + diff --git a/.github/ISSUE_TEMPLATE/how-to.md b/.github/ISSUE_TEMPLATE/how-to.md index f4375500a66..792970963bc 100644 --- a/.github/ISSUE_TEMPLATE/how-to.md +++ b/.github/ISSUE_TEMPLATE/how-to.md @@ -1,21 +1,22 @@ --- -name: How to -about: You have something specific to achieve and the existing documentation hasn't - covered how. +name: How to? +about: You have something specific to achieve and the existing documentation hasn't covered how. --- - -**Summary: What are you wanting to achieve?** +# How to? -**What code or approach do you have so far?** +## What are you wanting to achieve? -It is _always_ useful to see: +## What code or approach do you have so far? -+ **code of any policy declarations**, -+ **code of the calls to `.Execute/AndCapture/Async(...)`** + diff --git a/.github/ISSUE_TEMPLATE/request.md b/.github/ISSUE_TEMPLATE/request.md index 2d3272ae50f..fd85b56772b 100644 --- a/.github/ISSUE_TEMPLATE/request.md +++ b/.github/ISSUE_TEMPLATE/request.md @@ -1,16 +1,14 @@ --- -name: Request +name: Feature Request about: Suggest a feature request or improvement - --- -**Is your feature request related to a specific problem? Or an existing feature? Please describe.** - - -**Describe your proposed or preferred solution**: +# Feature Request +## Is your feature request related to a specific problem? Or an existing feature? -**Describe any alternative options you've considered**: +## Describe your proposed or preferred solution +## Describe any alternative options you've considered -**Any additional info?** +## Any additional info? diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index 794350c1463..8a95f176a23 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -1,12 +1,14 @@ - + -### The issue or feature being addressed +# Pull Request + +## The issue or feature being addressed -### Details on the issue fix or feature implementation +## Details on the issue fix or feature implementation -### Confirm the following +## Confirm the following - [ ] I started this PR by branching from the head of the default branch - [ ] I have targeted the PR to merge into the default branch diff --git a/.github/workflows/gh-pages.yml b/.github/workflows/gh-pages.yml index ed5e893d9d0..cfcec8167ec 100644 --- a/.github/workflows/gh-pages.yml +++ b/.github/workflows/gh-pages.yml @@ -22,6 +22,15 @@ jobs: - name: Checkout uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v4.1.0 + - name: Lint Markdown files + uses: DavidAnson/markdownlint-cli2-action@ed4dec634fd2ef689c7061d5647371d8248064f1 # v13.0.0 + with: + config: '.markdownlint.json' + globs: | + **/*.md + !CHANGELOG.md + !**/BenchmarkDotNet.Artifacts/**/*.md + - name: Setup .NET SDK uses: actions/setup-dotnet@3447fd6a9f9e57506b15f895c5b76d3b197dc7c2 # v3.2.0 diff --git a/.markdownlint.json b/.markdownlint.json new file mode 100644 index 00000000000..588de818ff8 --- /dev/null +++ b/.markdownlint.json @@ -0,0 +1,10 @@ +{ + "MD013": false, + "MD033": { + "allowed_elements": [ + "br", + "img", + "sub" + ] + } +} diff --git a/CHANGELOG.md b/CHANGELOG.md index d96d758172f..e3ec62e7140 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,5 @@ +# CHANGELOG + ## 8.0.0 * Updates for beta.2 by [@martincostello](https://github.com/martincostello) in https://github.com/App-vNext/Polly/pull/1580 diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md index 705e8cdfffe..07c19958e30 100644 --- a/CODE_OF_CONDUCT.md +++ b/CODE_OF_CONDUCT.md @@ -1 +1,7 @@ -Polly is part of the [.NET Foundation](https://dotnetfoundation.org/), and we ask our contributors to abide by their [Code of Conduct](https://www.dotnetfoundation.org/code-of-conduct). +# Code of Conduct + +Polly is part of the [.NET Foundation][dnf], and we ask our contributors to abide +by their [Code of Conduct][dnf-coc]. + +[dnf]: https://dotnetfoundation.org/ +[dnf-coc]: https://www.dotnetfoundation.org/code-of-conduct diff --git a/docs/advanced/dependency-injection.md b/docs/advanced/dependency-injection.md index 9ac4d23b399..bb65272df19 100644 --- a/docs/advanced/dependency-injection.md +++ b/docs/advanced/dependency-injection.md @@ -1,16 +1,22 @@ # Dependency injection -Starting with version 8, Polly provides features that make the integration of Polly with the .NET [`IServiceCollection`](https://learn.microsoft.com/dotnet/api/microsoft.extensions.dependencyinjection.iservicecollection) Dependency Injection (DI) container more streamlined. This is a thin layer atop the [resilience pipeline registry](../pipelines/resilience-pipeline-registry.md) which manages resilience pipelines. +Starting with version 8, Polly provides features that make the integration of Polly +with the .NET [`IServiceCollection`](https://learn.microsoft.com/dotnet/api/microsoft.extensions.dependencyinjection.iservicecollection) +Dependency Injection (DI) container more streamlined. This is a thin layer atop the +[resilience pipeline registry](../pipelines/resilience-pipeline-registry.md) which +manages resilience pipelines. ## Usage -To use the DI functionality, add the [`Polly.Extensions`](https://www.nuget.org/packages/Polly.Extensions) package to your project: +To use the DI functionality, add the [`Polly.Extensions`](https://www.nuget.org/packages/Polly.Extensions) +package to your project: ```sh dotnet add package Polly.Extensions ``` -Afterwards, you can use the `AddResiliencePipeline(...)` extension method to set up your pipeline: +Afterwards, you can use the `AddResiliencePipeline(...)` extension method to set +up your pipeline: ```cs @@ -44,20 +50,24 @@ await pipeline.ExecuteAsync( ``` -The `AddResiliencePipeline` extension method also registers the following services into the DI: +The `AddResiliencePipeline` extension method also registers the following services +into the DI container: - `ResiliencePipelineRegistry`: Allows adding and retrieving resilience pipelines. - `ResiliencePipelineProvider`: Allows retrieving resilience pipelines. - `IOptions>`: Options for `ResiliencePipelineRegistry`. > [!NOTE] -> The generic `string`` is inferred since the pipeline was defined using the "my-key" value. +> The generic `string`` is inferred since the pipeline was defined using the +> "my-key" value. -If you only need the registry without defining a pipeline, use the `AddResiliencePipelineRegistry(...)` method. +If you only need the registry without defining a pipeline, use the +`AddResiliencePipelineRegistry(...)` method. ### Generic resilience pipelines -You can also define generic resilience pipelines (`ResiliencePipeline`), as demonstrated below: +You can also define generic resilience pipelines (`ResiliencePipeline`), as +demonstrated below: ```cs @@ -92,7 +102,9 @@ await pipeline.ExecuteAsync( ## Dynamic reloads -Dynamic reloading is a feature of the pipeline registry that is also surfaced when using the `AddResiliencePipeline(...)` extension method. Use an overload that provides access to `AddResiliencePipelineContext`: +Dynamic reloading is a feature of the pipeline registry that is also surfaced when +using the `AddResiliencePipeline(...)` extension method. Use an overload that provides +access to `AddResiliencePipelineContext`: ```cs @@ -121,11 +133,14 @@ During a reload: - The callback re-executes. - The previous pipeline is discarded. -If an error occurs during reloading, the old pipeline remains, and dynamic reloading stops. +If an error occurs during reloading, the old pipeline remains, and dynamic +reloading stops. ## Resource disposal -Like dynamic reloading, the pipeline registry's resource disposal feature lets you register callbacks. These callbacks run when the pipeline is discarded, reloaded, or the registry is disposed at application shutdown. +Like dynamic reloading, the pipeline registry's resource disposal feature lets +you register callbacks. These callbacks run when the pipeline is discarded, reloaded, +or the registry is disposed at application shutdown. See the example below: @@ -145,11 +160,14 @@ services.AddResiliencePipeline("my-pipeline", (builder, context) => ``` -This feature ensures that resources are properly disposed when a pipeline reloads, discarding the old version. +This feature ensures that resources are properly disposed when a pipeline +reloads, discarding the old version. ## Complex pipeline keys -The `AddResiliencePipeline(...)` method supports complex pipeline keys. This capability allows you to define the structure of your pipeline and dynamically resolve and cache multiple instances of the pipeline with different keys. +The `AddResiliencePipeline(...)` method supports complex pipeline keys. This +capability allows you to define the structure of your pipeline and dynamically +resolve and cache multiple instances of the pipeline with different keys. Start by defining your complex key: @@ -174,7 +192,10 @@ services.AddResiliencePipeline(new MyPipelineKey("my-pipeline", string.Empty), b ``` -The "my-pipeline" pipeline is now registered. Note that the `InstanceName` is an empty string. While we're registering the builder action for a specific pipeline, the `InstanceName` parameter isn't used during the pipeline's registration. Some further modifications are required for this to function. +The "my-pipeline" pipeline is now registered. Note that the `InstanceName` is an +empty string. While we're registering the builder action for a specific pipeline, +the `InstanceName` parameter isn't used during the pipeline's registration. Some +further modifications are required for this to function. Introduce the `PipelineNameComparer`: @@ -207,11 +228,16 @@ services Let's summarize our actions: -- We assigned the `PipelineNameComparer` instance to the `BuilderComparer` property. This action changes the default registry behavior, ensuring that only the `PipelineName` is used to find the associated builder. -- We used the `InstanceNameFormatter` delegate to represent the `MyPipelineKey` as an instance name for telemetry purposes, keeping the instance name as it is. -- Likewise, the `BuilderNameFormatter` delegate represents the `MyPipelineKey` as a builder name in telemetry. +- We assigned the `PipelineNameComparer` instance to the `BuilderComparer` property. + This action changes the default registry behavior, ensuring that only the + `PipelineName` is used to find the associated builder. +- We used the `InstanceNameFormatter` delegate to represent the `MyPipelineKey` + as an instance name for telemetry purposes, keeping the instance name as it is. +- Likewise, the `BuilderNameFormatter` delegate represents the `MyPipelineKey` as + a builder name in telemetry. -Finally, use the `ResiliencePipelineProvider` to dynamically create and cache multiple instances of the same pipeline: +Finally, use the `ResiliencePipelineProvider` to dynamically create +and cache multiple instances of the same pipeline: ```cs @@ -225,10 +251,11 @@ ResiliencePipeline instanceB = pipelineProvider.GetPipeline(new MyPipelineKey("m ``` - ## Patterns and anti-patterns -Over the years, many developers have used Polly in various ways. Some of these recurring patterns may not be ideal. This section highlights the recommended practices and those to avoid. +Over the years, many developers have used Polly in various ways. Some of these +recurring patterns may not be ideal. This section highlights the recommended practices +and those to avoid. ### 1 - Accessing the `IServiceCollection` instead of `IServiceProvider` @@ -283,4 +310,5 @@ services.AddResiliencePipeline("myFavoriteStrategy", static (builder, context) = **Reasoning**: -This approach uses the already built `ServiceProvider` and uses the same instance before every retry attempts. +This approach uses the already built `ServiceProvider` and uses the same instance +before every retry attempts. diff --git a/docs/api/index.md b/docs/api/index.md index 78dc9c00575..64a1235da3f 100644 --- a/docs/api/index.md +++ b/docs/api/index.md @@ -1,2 +1,4 @@ # PLACEHOLDER -TODO: Add .NET projects to the *src* folder and run `docfx` to generate **REAL** *API Documentation*! + +TODO: Add .NET projects to the *src* folder and run `docfx` to +generate **REAL** *API Documentation*!