Exemplo n.º 1
0
        // Recursive, retry-logic, state-machine function
        public async Task <Todo> Start()
        {
            // let's keep track of our function's status
            Console.WriteLine();
            Console.WriteLine("status: " + Status.ToString());
            Console.WriteLine("retries: " + Retries.ToString());

            // if Start() is called with the CircuitBreaker status being OPEN
            if (Status == Status.OPEN)
            {
                try
                {
                    // lets do our initial call
                    return(await Call().ConfigureAwait(false));
                }
                catch (Exception badResponse)
                {
                    // do something with bad_response...
                    Console.WriteLine(badResponse.Message);
                    // set status to HALFOPEN because our initial request failed
                    Status = Status.HALFOPEN;
                    Retries++;
                    return(await Start().ConfigureAwait(false)); // retry with our Status being HALFOPEN
                }
            }

            // if Start() is called with the CircuitBreaker status being HALFOPEN
            if (Status == Status.HALFOPEN)
            {
                Console.WriteLine("TIMEOUT...");
                Thread.Sleep(TimeOut);
                try
                {
                    // try a call again
                    return(await Call().ConfigureAwait(false));
                }
                catch
                {
                    if (Retries < RetryCount) // did we retry too many times already?
                    {
                        Retries++;
                        return(await Start().ConfigureAwait(false)); // Start this function again with the same status HALFOPEN
                    }

                    // looks like we retried too many times, time to set status to CLOSED
                    Status = Status.CLOSED;
                    return(await Start().ConfigureAwait(false));
                }
            }

            // if Start() is called with the CircuitBreaker status being CLOSED
            if (Status == Status.CLOSED)
            {
                // we throw our final error message
                throw new Exception($"CircuitBreaker failed for { Url} : { Retries} " +
                                    $"times: TimeOut { TimeOut}");
            }

            return(await Start().ConfigureAwait(false)); // this should never be reached, but acts as a safety-net
        }