当前位置:网站首页>A concurrent rule verification implementation

A concurrent rule verification implementation

2022-07-07 07:25:00 Dotnet cross platform

Recently, I am doing a simple risk control , One of the requirements is like this , When the main request parameters arrive , Based on these parameters , Look at several concurrency rules , These rules have their own verification logic , The execution time of each rule is uncertain , When the rules After the execution , Return to main request , The main request verifies the returned result according to the rule , So as to decide whether to immediately response request , But other late rules , Continue to complete the following verification , To get the verification results , For later use .

Preliminary .net The code is implemented in this way :

using System.Threading.Channels;


var builder = WebApplication.CreateBuilder(args);


var app = builder.Build();


app.MapGet("/test", async () =>
{
    Console.WriteLine($" Starting time  {DateTime.Now.ToString("HH:mm:ss")}");
    var channels = new List<Channel<Parameter>>();
    var len = 5;
    // establish Channel, And associated with ReadAsync Method 
    for (int i = 0; i < len; i++)
    {
        var channel = Channel.CreateUnbounded<Parameter>(new UnboundedChannelOptions() { AllowSynchronousContinuations = true });
        channels.Add(channel);
        await Task.Factory.StartNew(async () =>
        {
            Console.WriteLine($"Task {i}");
            await ReadAsync(channel);
        });
    }
    // towards Channel Send a message 
    for (int i = 0; i < channels.Count; i++)
    {
        var channel = channels[i];
        await channel.Writer.WriteAsync(new Parameter { I = i });
        Console.WriteLine($"Write {i}");
    }


    // Read back Channel, If there is a return True,API Return early , Leave the Channel to RemainingReadAsync perform 
    for (int i = 0; i < channels.Count; i++)
    {
        var channel = channels[i];
        if (channel != null && await channel.Reader.WaitToReadAsync())
        {
            if (channel.Reader.TryRead(out var par))
            {
                if(par.Result)
                {
                    Console.ForegroundColor = ConsoleColor.Green;
                }
                Console.WriteLine($"I:{par.I},Result:{par.Result},{DateTime.Now.ToString("HH:mm:ss")}");
                Console.ResetColor();
                if (par.Result)
                {
                    // Push the rest to a thread for execution 
                    for (var r = i + 1; r < channels.Count; r++)
                    {
                        await Task.Factory.StartNew(async () =>
                        {
                            await RemainingReadAsync(channels[r]);
                        });
                    }
                    return TypedResults.Ok($" complete , Yes ,{DateTime.Now.ToString("HH:mm:ss")}");


                }
            }
        }
    }
    return TypedResults.Ok($" complete , No, ,{DateTime.Now.ToString("HH:mm:ss")}");
});


app.Run();
// Deal with the rest Channelr Method 
async Task RemainingReadAsync(Channel<Parameter> channel)
{
    if (channel != null && await channel.Reader.WaitToReadAsync())
    {
        if (channel.Reader.TryRead(out var par))
        {
            Console.WriteLine($"I:{par.I},Result:{par.Result},{DateTime.Now.ToString("HH:mm:ss")}");
        }
    }
}
// Read Channel Methods 
async Task ReadAsync(Channel<Parameter> channel)
{
    if (channel != null && await channel.Reader.WaitToReadAsync())
    {
        if (channel.Reader.TryRead(out var par))
        {
            await Task.Delay((par.I + 1) * 1000);
            if (par.I == 2)
            {
                par.Result = true;
            }
            else
            {
                par.Result = false;
            }
            await channel.Writer.WriteAsync(par);
        }
    }
}


// Parameters 
class Parameter
{
    public int I { get; set; }
    public bool Result { get; set; }
}

The figure below is the result of the implementation , When five tasks are invoked concurrently , Write data concurrently , In execution , The third condition is satisfied , On 21:59:13 Return request , But the next two , Still guaranteed .

f1c2cd3449c0b415643dc29bed7c8cd8.png

This Demo Just simply completed the logic , The performance needs to be further tested, verified and improved .

原网站

版权声明
本文为[Dotnet cross platform]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/188/202207070339122807.html