Skip to content

Timeout not working as expected [EDIT: Async pessimistic timeout does not timeout synchronous delegates] #340

@udlose

Description

@udlose

Please clarify if I am misunderstanding how the Timeout Policy works. I would expect this to cause a TimeoutRejectedException but it does not. I have a Task.Delay(4000).Wait() defined in the func that Polly executes. I would think that anything in that Func that takes longer than the specified Timeout would throw TimeoutRejectedException but this is not the behavior I'm seeing.

Taken from Polly samples

            // Define our timeout policy: time out after 2 seconds.  We will use the pessimistic timeout strategy, which forces a timeout - even when the underlying delegate doesn't support it.
            var timeoutPolicy = Policy
                .TimeoutAsync(
                    TimeSpan.FromSeconds(2),
                    TimeoutStrategy.Pessimistic,
                    onTimeoutAsync: (callContext, span, task) =>
                    {
                        return Task.CompletedTask;
                    }
                );

            // Define our waitAndRetry policy: keep retrying with 4 second gaps.  This is (intentionally) too long: to demonstrate that the timeout policy will time out on this before waiting for the retry.
            var waitAndRetryPolicy = Policy
                .Handle<Exception>() // Exception filtering!  We don't retry if the inner circuit-breaker judges the underlying system is out of commission!
                .WaitAndRetryForeverAsync(
//                    attempt => TimeSpan.FromSeconds(4),
                      attempt => TimeSpan.FromMilliseconds(100),
                  (exception, calculatedWaitDuration) =>
                    {
                    });

            FallbackPolicy<String> fallbackForAnyException = Policy<String>
                .Handle<Exception>()
                .FallbackAsync(
                    fallbackAction: /* Demonstrates fallback action/func syntax */ async ct =>
                    {
                    },
                    onFallbackAsync: async e =>
                    {
                    }
                );

            PolicyWrap<String> policyWrap = fallbackForAnyException.WrapAsync(timeoutPolicy).WrapAsync(waitAndRetryPolicy);

            while (!Console.KeyAvailable && !cancellationToken.IsCancellationRequested)
            {
                try
                {
                    Func<CancellationToken, Task<string>> foo = (ct) =>
                    {
                        //shouldn't this cause a TimeoutRejectedException???
                        Task.Delay(4000).Wait();  
                        return Task.FromResult("hello");
                    };

                    string msg = await policyWrap.ExecuteAsync(foo, cancellationToken);
                }
                catch (Exception e)
                {
                }

                // Wait half second
//                await Task.Delay(TimeSpan.FromSeconds(0.5), cancellationToken);
            }

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions