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