示例#1
0
        public async Task CancellationTestCase4()
        {
            CancellationTokenSource instanceCancellationTokenSource = new CancellationTokenSource();
            CancellationToken       instanceCancellationToken       = instanceCancellationTokenSource.Token;

            CancellationTokenSource delegateCancellationTokenSource = new CancellationTokenSource();
            CancellationToken       delegateCancellationToken       = delegateCancellationTokenSource.Token;

            TaskCompletionSource <bool> taskCompletionSourceSetWhenDelegateRuns = new TaskCompletionSource <bool>();

            Func <TaskCompletionSource <bool>, CancellationToken, Task <TestResponse> > funcWhichIsAFairlyLongRunningTask = async(req, token) =>
            {
                req.SetResult(true);

                await Task.Delay(TimeSpan.FromMinutes(3).Duration(), token).ConfigureAwait(false);

                return(new TestResponse());
            };

            using (ThrottledFunctionExecutor <TaskCompletionSource <bool>, TestResponse> tfe = new ThrottledFunctionExecutor <TaskCompletionSource <bool>, TestResponse>
                                                                                                   (funcWhichIsAFairlyLongRunningTask, instanceCancellationToken))
            {
                CustomerThrottle customerThrottle = CustomerThrottle.Create("ExampleKey", 1);

                Task <TestResponse> response = tfe.ExecuteThrottledAsync(customerThrottle, taskCompletionSourceSetWhenDelegateRuns,
                                                                         delegateCancellationToken);

                await taskCompletionSourceSetWhenDelegateRuns.Task.ConfigureAwait(false);

                // the delegate is running at this point, and so all of the internal cancellation logic has been cleared

                await Task.Delay(TimeSpan.FromSeconds(5).Duration()).ConfigureAwait(false); // just to ensure we've hit the Task.Delay in the delegate

                try
                {
                    delegateCancellationTokenSource.Cancel();

                    var result = await response.ConfigureAwait(false);

                    Assert.Fail(); // OperationCanceledException should have been thrown
                }
                catch (OperationCanceledException)
                {
                    return;
                }
                catch (Exception)
                {
                    Assert.Fail();
                }

                Assert.Fail();
            }
        }
        private async Task SimulateRequestsAsync(CustomerThrottle ct, ThrottledFunctionExecutor <TestRequest, TestResponse> tfe, TestCounter counter)
        {
            try
            {
                while (true)
                {
                    var response = await tfe.ExecuteThrottledAsync(ct, new TestRequest()).ConfigureAwait(false);

                    counter.Add();
                }
            }
            catch (OperationCanceledException)
            {
            }
            catch (Exception)
            {
                throw;
            }
        }
示例#3
0
        public async Task CancellationTestCase3()
        {
            CancellationTokenSource instanceCancellationTokenSource = new CancellationTokenSource();
            CancellationToken       instanceCancellationToken       = instanceCancellationTokenSource.Token;

            CancellationTokenSource delegateCancellationTokenSource = new CancellationTokenSource();
            CancellationToken       delegateCancellationToken       = delegateCancellationTokenSource.Token;

            instanceCancellationTokenSource.Cancel();

            Func <TestRequest, CancellationToken, Task <TestResponse> > funcPlaceholderDelegateThatWillNeverRun = async(req, token) =>
            {
                await Task.Delay(1).ConfigureAwait(false);

                throw new NotImplementedException();
            };

            using (ThrottledFunctionExecutor <TestRequest, TestResponse> tfe = new ThrottledFunctionExecutor <TestRequest, TestResponse>
                                                                                   (funcPlaceholderDelegateThatWillNeverRun, instanceCancellationToken))
            {
                CustomerThrottle customerThrottle = CustomerThrottle.Create("ExampleKey", 1);

                try
                {
                    TestResponse response = await tfe.ExecuteThrottledAsync(customerThrottle, new TestRequest(),
                                                                            delegateCancellationToken).ConfigureAwait(false);

                    Assert.Fail();
                }
                catch (OperationCanceledException)
                {
                    return;
                }
                catch (Exception)
                {
                    Assert.Fail();
                }

                Assert.Fail();
            }
        }
#pragma warning disable CS1998 // Async method lacks 'await' operators and will run synchronously
        public async Task ChangingRateTest1()
#pragma warning restore CS1998 // Async method lacks 'await' operators and will run synchronously
        {
            Func <TestRequest, CancellationToken, Task <TestResponse> > testDelegateFunction = async(req, token) =>
            {
                return(await Task.Run(() => { return new TestResponse(); }).ConfigureAwait(false));
            };

            // customer 1: Initially 1 request per second
            CustomerThrottle customerThrottle1rate1 = CustomerThrottle.Create("1", 1);
            //  ... then 60 request per second
            CustomerThrottle customerThrottle1rate2 = CustomerThrottle.Create("1", 60);

            TestCounter testCounter1 = new TestCounter();

            CancellationTokenSource tfeTokenSource = new CancellationTokenSource();

            using (ThrottledFunctionExecutor <TestRequest, TestResponse> tfe = new ThrottledFunctionExecutor <TestRequest, TestResponse>
                                                                                   (testDelegateFunction, tfeTokenSource.Token))
            {
                CancellationTokenSource cts1 = new CancellationTokenSource();
                CancellationTokenSource cts2 = new CancellationTokenSource();

                var t1 = new Task(async() =>
                {
                    await SimulateRequestsAsync(customerThrottle1rate1, tfe, testCounter1, cts1.Token).ConfigureAwait(false);
                });

                var t2 = new Task(async() =>
                {
                    await SimulateRequestsAsync(customerThrottle1rate2, tfe, testCounter1, cts2.Token).ConfigureAwait(false);
                    return;
                });


                Stopwatch sw1 = new Stopwatch();
                Stopwatch sw2 = new Stopwatch();

                t1.Start();

                sw1.Start();

                while (true)
                {
                    Thread.Sleep(1);
                    if (sw1.Elapsed.TotalMilliseconds >= 59750)
                    {
                        break;
                    }
                }

                testCounter1.stopCount = true;
                sw1.Stop();

                cts1.Cancel();

                Task.WaitAll(t1);

                t2.Start();

                sw2.Start();
                testCounter1.stopCount = false;

                while (true)
                {
                    Thread.Sleep(1);
                    if (sw2.Elapsed.TotalMilliseconds >= 59750)
                    {
                        break;
                    }
                }

                testCounter1.stopCount = true;
                sw2.Stop();

                cts2.Cancel();

                Task.WaitAll(t2);

                // Total requests = 60 + 3600 = 3660
                // Total seconds = ~119.5
                // r/s = 30.63

                TimeSpan totalElapsed = sw1.Elapsed + sw2.Elapsed;

                Assert.AreEqual(30.63, testCounter1.count / totalElapsed.TotalSeconds, 0.75);
            }
        }
#pragma warning disable CS1998 // Async method lacks 'await' operators and will run synchronously
        public async Task ThrottlingRateOver2MinutesTest1()
#pragma warning restore CS1998 // Async method lacks 'await' operators and will run synchronously
        {
            Func <TestRequest, CancellationToken, Task <TestResponse> > testDelegateFunction = async(req, token) =>
            {
                return(await Task.Run(() => { return new TestResponse(); }).ConfigureAwait(false));
            };

            // customer 1: 1 request per second
            CustomerThrottle customerThrottle1 = CustomerThrottle.Create("1", 1);
            // customer 2: 2 requests per second
            CustomerThrottle customerThrottle2 = CustomerThrottle.Create("2", 2);
            // customer 3: 4 requests per second
            CustomerThrottle customerThrottle3 = CustomerThrottle.Create("3", 4);
            // customer 4: 120 requests per second
            CustomerThrottle customerThrottle4 = CustomerThrottle.Create("4", 120);

            TestCounter testCounter1 = new TestCounter();
            TestCounter testCounter2 = new TestCounter();
            TestCounter testCounter3 = new TestCounter();
            TestCounter testCounter4 = new TestCounter();

            CancellationTokenSource tokenSource = new CancellationTokenSource();

            using (ThrottledFunctionExecutor <TestRequest, TestResponse> tfe = new ThrottledFunctionExecutor <TestRequest, TestResponse>
                                                                                   (testDelegateFunction, tokenSource.Token))
            {
                var t1 = new Task(async() =>
                {
                    await SimulateRequestsAsync(customerThrottle1, tfe, testCounter1).ConfigureAwait(false);
                });

                var t2 = new Task(async() =>
                {
                    await SimulateRequestsAsync(customerThrottle2, tfe, testCounter2).ConfigureAwait(false);
                    return;
                });

                var t3 = new Task(async() =>
                {
                    await SimulateRequestsAsync(customerThrottle3, tfe, testCounter3).ConfigureAwait(false);
                    return;
                });

                var t4 = new Task(async() =>
                {
                    await SimulateRequestsAsync(customerThrottle4, tfe, testCounter4).ConfigureAwait(false);
                    return;
                });

                Stopwatch sw = new Stopwatch();
                sw.Start();

                t1.Start();
                t2.Start();
                t3.Start();
                t4.Start();

                while (true)
                {
                    Thread.Sleep(1);
                    if (sw.Elapsed.TotalMilliseconds >= 59950)
                    {
                        break;
                    }
                }

                testCounter1.stopCount = true;
                testCounter2.stopCount = true;
                testCounter3.stopCount = true;
                testCounter4.stopCount = true;

                sw.Stop();

                tokenSource.Cancel();

                Task.WaitAll(t1, t2, t3, t4);

                // customer 1: 1 request per second
                Assert.AreEqual(1, testCounter1.count / sw.Elapsed.TotalSeconds, 0.05);

                // customer 2: 2 requests per second
                Assert.AreEqual(2, testCounter2.count / sw.Elapsed.TotalSeconds, 0.10);

                // customer 3: 4 requests per second
                Assert.AreEqual(4, testCounter3.count / sw.Elapsed.TotalSeconds, 0.4);

                // customer 4: 120 requests per second
                Assert.AreEqual(120, testCounter4.count / sw.Elapsed.TotalSeconds, 12);
            }
        }