dotnet / dotNext

Next generation API for .NET
https://dotnet.github.io/dotNext/
MIT License
1.56k stars 119 forks source link

Raft Cluster Asp.net Core Dynamically AddMemberAsync #196

Closed guillaume-chervet closed 8 months ago

guillaume-chervet commented 8 months ago

Hi,

Thank you again for this wonderful library. I would like to autoscale a very small database on kubernetes (with access to the kubernetes API). I'am testing to add dynamically some members.

My code is crashing, i do not know if it is possible to do that. The documentation seem to tell it is possibile with the HTTP implementation.

My test code : https://github.com/AxaFrance/SlimFaas/blob/b46f4675171d2a7a9618ec36744a5832e8f2c274/src/SlimData/Startup.cs#L251C17-L276C20

endpoints.MapPost("AddMember", async context =>
                {
                    var cluster = context.RequestServices.GetRequiredService< IRaftCluster>();

                    try
                    {
                        var form = await context.Request.ReadFormAsync();
                        var key = string.Empty;
                        var value = string.Empty;
                        foreach (var formData in form)
                        {
                            value = formData.Value.ToString();
                            if (cluster.Members
                                    .Count(m => m.EndPoint == new UriEndPoint(new(value, UriKind.Absolute))) == 0)
                            {
                                await ((IRaftHttpCluster)cluster).AddMemberAsync(new Uri(value), context.RequestAborted);
                            }
                            break;
                        }
                        await context.Response.WriteAsync("", context.RequestAborted); 
                    }
                    catch (Exception e)
                    {
                        Console.WriteLine("Unexpected error {0}", e);
                    }
                });

The code is crashing on line :

  await ((IRaftHttpCluster)cluster).AddMemberAsync(new Uri(value), context.RequestAborted);

image

sakno commented 8 months ago

AddMember must be called for leader node only and the node must be online. Dynamic membership is supported for all network transports, not only for HTTP.

sakno commented 8 months ago

Exception should be clear about attempt to add member on the follower node.

guillaume-chervet commented 8 months ago

Thank you very much @sakno , i understand now.

So a node cannot start whithout any member.

sakno commented 8 months ago

A new node should be started in Standby state. Then, you need to inform leader node about new node by calling AddMemberAsync.

sakno commented 8 months ago

4.14.4 release has been published with correct exception type. If you need further assistance, please create a discussion.