GithubHelp home page GithubHelp logo

app-vnext / polly-samples Goto Github PK

View Code? Open in Web Editor NEW
274.0 29.0 129.0 26.85 MB

Provides sample implementations of the Polly library. The intent of this project is to help newcomers kick-start their use of Polly within their own projects.

License: GNU General Public License v2.0

C# 100.00%

polly-samples's Introduction

Polly-Samples

Polly logo

This repository provides sample implementations of using the Polly library in a .NET application.

The intent of this project is to help newcomers kick-start the use of Polly within their own projects.

The samples demonstrate the policies in action, against faulting endpoints.

Projects

The solution contains three applications and one class library:

flowchart LR
    console{{PollyTestClientConsole}}
    wpf{{PollyTestClientWPF}}
    lib>PollyDemos]
    api[/PollyTestWebApi\]

    console -- uses --> lib
    wpf -- uses --> lib
    lib -- invokes --> api
Loading

Demos

General information

  • The demos run against an example 'faulting server'.
    • To simulate failure, the dummy server rejects more than 3 calls in any five-second period.
  • Be sure to read the <summary> at the top of each demo.
    • This explains the intent of that demo, and what resilience it adds to its handling of the calls to the 'faulting server'.
  • Sometimes the <summary> also highlights what this demo doesn't achieve, which is often picked up in the following demo.
  • Explore the demos in sequence for best understanding.

Sequence

# Description Link
00 No strategy Code
01 Retry N times Code
02 Wait and retry N times Code
03 Wait and retry N times, N big enough to guarantee success Code
04 Wait and retry forever Code
05 Wait and retry with exponential back-off Code
06 Wait and retry nesting circuit breaker Code
07 Wait and retry chaining with circuit breaker by using Pipeline Code
08 Fallback, Retry, and CircuitBreaker in a Pipeline Code
09 Fallback, Timeout, and Retry in a Pipeline Code
10 Without isolation: Faulting calls swamp resources,
also prevent good calls
Code
11 With isolation: Faulting calls separated,
do not swamp resources, good calls still succeed
Code
12 Hedging in latency mode Code
13 Hedging in fallback mode: retry only Code
14 Hedging in fallback mode: retry with fallback Code
15 Hedging in parallel mode Code
16 Entity Framework with retry N times Code

Want further information?

Slide decks

View the slides presented at NDC, DevIntersections and other conferences.

You are welcome to use and adapt this presentation for not-for-profit presentations of Polly to co-workers, user groups and similar, subject to the condition that references to the .NET Foundation, App-vNext and the individual members of the Polly team are retained.

polly-samples's People

Contributors

bjartwolf avatar dependabot[bot] avatar dreisenberger avatar eugeneogongo avatar joelhulen avatar kabua avatar martincostello avatar peter-csala avatar reisenberger avatar renato04 avatar vincentshow avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

polly-samples's Issues

Minor Issue: Can never be Null

Just trying to promote good programming practices.

The first line of each test reads:
if (cancellationToken == null) throw new ArgumentNullException(nameof(cancellationToken));

CancellationToken is a struct and thus can never be null.

CS0037 - Cannot convert null to 'type' because it is a non-nullable value type.

See: cs0037

While I love testing arguments for valid state and it is better to check than not to check, this check is redundant and more importantly is teaching junior developers, who may not know any better, that structs might be null - which by definition they can't.

Finalize (OnSuccess Action) the WaitAndRetryAsync with a WrapAsync Policy

I have a FallbackAsync Policy combined with a WaitAndRetryAsync Policy.
Both Policies are wrapped together with WrapAsync.
FallbackPolicy.WrapAsync(RetryPolicy). This works.

Is have a need to add some Finalizer eq. When the WaitAndRetryAsync succeeds like the fallbackAction but in the WaitAndRetryAsync

Adding sample code for hedging

After the V8 migration is done we could add new samples for missing strategies.

As far as I can see all strategies are covered with one or multiple demos, except Hedging (since it is newly introduced in V8 :))

timeout policy not working

I'm trying out the timeout policy with polly. I expect an exception to be thrown after 1 sec passed because that is the timeout upper limit I set up. But currently, no exception will be thrown and the method LongOperation() returns normally after around 5 secs.

Why does the timeout policy not work in this case?

static void Main(string[] args)
{
    Stopwatch stopwatch = new Stopwatch();
    stopwatch.Start();

    timeoutPolicy().GetAwaiter().GetResult();

    stopwatch.Stop();
    Console.WriteLine("Time elapsed: {0}", stopwatch.Elapsed);
    Console.ReadKey();
}

static async Task timeoutPolicy()
{
    AsyncTimeoutPolicy<HttpResponseMessage> timeoutPolicy = Policy.TimeoutAsync<HttpResponseMessage>(1); // setup the timeout limit to be 1 sec

    HttpResponseMessage response = await timeoutPolicy.ExecuteAsync((ct) => LongOperation(), CancellationToken.None);

    Console.WriteLine(response);



}

static Task<HttpResponseMessage> LongOperation()
{
    return Task<HttpResponseMessage>.Factory.StartNew(() =>
    {
        Thread.Sleep(5000); // Sleep 5 seconds
        return new HttpResponseMessage()
        {
            StatusCode = HttpStatusCode.BadRequest
        };

    });
}

Discussion about getting rid of the sync demos

I'm proposing to get rid of the sync demos. Here is my rationale:

  • Prior V8 you have to define separate policies for sync and async methods
  • Since V8 you have a unified strategy which can be executed both in sync and in async way
  • After the V8 migration the sync demos look like code-duplicates rather than great additions

Is there any objection to delete the sync demos?

Documentation - SSL issue

I had troubles with SSL on Linux although I ran the below command.

dotnet dev-certs https --trust

I had this issue for any http or https for localhost connections only.

On further investigation, I was able to mitigate this, by the fix here . I think this can be udated in the README.

Also, I saw that pressing any key during the demo run can trigger the demo run summary till then and stop the run. I am assuming it is nice to have this documented in the README as well.

circuitBreakerStrategy never opens

In the Demo06_WaitAndRetryNestingCircuitBreaker the only message logged is "Strategy logging: ...". the "circuit breaker strategy: break if the action fails at least 4 times in a row" never happens?

Am I missing something?

Exception not re-thrown

In the following code the inner method InvokeAsync is throwing an OnlineException but I can never catch it what is re-thrown is a simple Exception:

//-- in a singleton
CircuitBreakerPolicy = Policy
    .Handle<Exception>()
    .CircuitBreakerAsync(
        exceptionsAllowedBeforeBreaking: ExceptionsAllowedForCircuiteBreaker,
        durationOfBreak: TimeSpan.FromSeconds(BreakTime),
        onBreak: (ex, breakDelay) =>
        {
            Debug.Log($".Breaker logging: Breaking the circuit for {breakDelay.TotalMilliseconds} ms!");
            Debug.Log($"..due to: + {ex.Message}");
        },
        onReset: () => Debug.Log(".Breaker logging: Call ok! Closed the circuit again!"),
        onHalfOpen: () => Debug.Log(".Breaker logging: Half-open: Next call is a trial!")
    );
//--

public virtual async Task<IOnlineResponse> Process(CancellationToken ct)
{
    Debug.Log($"Processing = {Type}");

    State = new RequestState();
    U serviceResponse = null;

    AsyncTimeoutPolicy timeoutPolicy = Policy.TimeoutAsync(TimeOut);

    AsyncRetryPolicy waitAndRetryPolicy = Policy
            .Handle<Exception>(e => !(e is BrokenCircuitException))
            .WaitAndRetryAsync(
            retryCount: DefaultRetryCount,
            attempt => TimeSpan.FromMilliseconds(AttemptDelay),
            (exception, calculatedWaitDuration) =>
            {
                Debug.Log($".Request exception (will retry): " + exception.Message);
            });

    AsyncPolicyWrap policyWrap = Policy.WrapAsync(timeoutPolicy, waitAndRetryPolicy, CircuitBreaker.Instance.CircuitBreakerPolicy);

    try
    {
        serviceResponse = await policyWrap.ExecuteAsync(async (cancellationToken) =>
        {
            await CheckConnectivity(cancellationToken);
            return await InvokeAsync(cancellationToken);
        }, ct, continueOnCapturedContext: true);

        State.Status = RequestStatus.Success;
        State.Message = "";
    }
    catch (OnlineException ex)
    {
        State.Status = OnlineExceptionStatusToRequestStatus(ex.StatusCode);
        State.Message = ex.ToString();
    }
    catch (Exception ex)
    {
        State.Status = RequestStatus.Failed;
        State.Message = ex.ToString();
    }

    Debug.Log($"Response = {Type} - {State.Status}");

    return new V { State = State, Response = serviceResponse };
}

AsyncDemo09_Wrap_Fallback_Timeout_WaitAndRetry throws

This doesn't seem to be part of the demo.

Demo was canceled: AsyncDemo09_Wrap_Fallback_Timeout_WaitAndRetry
.Log,then retry: Cannot access a disposed object.
Object name: 'System.Net.Http.HttpClient'.
Demo already stopped.
Unobserved task exception: System.AggregateException: A Task's exception(s) were not observed either by Waiting on the Task or accessing its Exception property. As a result, the unobserved exception was rethrown by the finalizer thread. ---> System.ObjectDisposedException: The CancellationTokenSource has been disposed.
   at System.Threading.CancellationTokenSource.ThrowObjectDisposedException()
   at System.Threading.CancellationTokenSource.InternalRegister(Action`1 callback, Object stateForCallback, SynchronizationContext targetSyncContext, ExecutionContext executionContext)
   at System.Threading.CancellationToken.Register(Action`1 callback, Object state, Boolean useSynchronizationContext, Boolean useExecutionContext)
   at System.Threading.CancellationToken.InternalRegisterWithoutEC(Action`1 callback, Object state)
   at System.Threading.Tasks.Task.Delay(Int32 millisecondsDelay, CancellationToken cancellationToken)
   at System.Threading.Tasks.Task.Delay(TimeSpan delay, CancellationToken cancellationToken)
   at Polly.Retry.AsyncRetryEngine.<ImplementationAsync>d__0`1.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Polly.AsyncPolicy.<ExecuteAsync>d__21`1.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Polly.Wrap.AsyncPolicyWrapEngine.<>c__DisplayClass1_0`1.<<ImplementationAsync>b__0>d.MoveNext()
   --- End of inner exception stack trace ---
---> (Inner Exception #0) System.ObjectDisposedException: The CancellationTokenSource has been disposed.
   at System.Threading.CancellationTokenSource.ThrowObjectDisposedException()
   at System.Threading.CancellationTokenSource.InternalRegister(Action`1 callback, Object stateForCallback, SynchronizationContext targetSyncContext, ExecutionContext executionContext)
   at System.Threading.CancellationToken.Register(Action`1 callback, Object state, Boolean useSynchronizationContext, Boolean useExecutionContext)
   at System.Threading.CancellationToken.InternalRegisterWithoutEC(Action`1 callback, Object state)
   at System.Threading.Tasks.Task.Delay(Int32 millisecondsDelay, CancellationToken cancellationToken)
   at System.Threading.Tasks.Task.Delay(TimeSpan delay, CancellationToken cancellationToken)
   at Polly.Retry.AsyncRetryEngine.<ImplementationAsync>d__0`1.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Polly.AsyncPolicy.<ExecuteAsync>d__21`1.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Polly.Wrap.AsyncPolicyWrapEngine.<>c__DisplayClass1_0`1.<<ImplementationAsync>b__0>d.MoveNext()<---
.

No Mac user interface

Hello

Something I noted while experimenting with Polly Samples is the lack of UI for Mac users, just the command line utility. I created a Blazor web app connected to the api. It needs a bit of polishing but would you be interested in a PR being submitted to add this to the repo?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.