Retarder – Making a strategy to wait–part 3
Now I want to make the await configurable. To remind , first is just a random delay ( or static delay). The others are
- Delay execution of some endpoints, based on how frequent are their uses
- Delay execution based on headers / query string / routes
- Delay execution based on client IP
- Delay execution based on the response
The best design pattern for this is Strategy https://en.wikipedia.org/wiki/Strategy_pattern . Also, because I want to apply multiple await types ( maybe in order, maybe to compose) , a simple Command Pattern will be enough.
So, let’s see how it looks now:
using System.Threading.Tasks; namespace NetCoreRetarderCore { public interface IStrategyAwait { Task<IStrategyAwait> AwaitDelay(); } }
So now let’s see the implementation of a StrategyAwaitFixed
using System; using System.Threading.Tasks; namespace NetCoreRetarderCore { public class StrategyAwaitFixed : IStrategyAwait { private readonly int milliseconds; public StrategyAwaitFixed(int milliseconds) { this.milliseconds = milliseconds; } public async Task<IStrategyAwait> AwaitDelay() { Console.WriteLine($"waiting {milliseconds}"); if (milliseconds < 1) return null; await Task.Delay(milliseconds); Console.WriteLine($"finished waiting {milliseconds}"); return null; } } }
Now the Retarder Middleware should apply the awaiter one by one
using Microsoft.AspNetCore.Http; using System; using System.Threading.Tasks; namespace NetCoreRetarderCore { public class RetarderMiddleware : IMiddleware { private IStrategyAwait strategyAwait; public RetarderMiddleware(IStrategyAwait strategyAwait) { this.strategyAwait = strategyAwait; } public async Task InvokeAsync(HttpContext context, RequestDelegate next) { while (strategyAwait != null) strategyAwait = await strategyAwait?.AwaitDelay(); await next(context); } } }
The code from middleware extension is modified as generating a new random each time:
using Microsoft.AspNetCore.Builder; using Microsoft.Extensions.DependencyInjection; using System; using System.Collections.Generic; using System.Text; namespace NetCoreRetarderCore { public static class RetarderExtensions { public static void AddRetarder(this IServiceCollection serviceCollection) { serviceCollection .AddTransient<IStrategyAwait, StrategyAwaitFixed>( it => { var random = new Random(); var awaitMilliseconds = random.Next(1, 1000); return new StrategyAwaitFixed(awaitMilliseconds); } ); serviceCollection.AddTransient<RetarderMiddleware>(); } public static void UseRetarder(this IApplicationBuilder app) { app.UseMiddleware<RetarderMiddleware>(); } } }
Full Code Source at https://github.com/ignatandrei/NetCoreRetarder/commits/version3_Making_a_strategy_to_wait
Leave a Reply