Marfusios / websocket-client

🔧 .NET/C# websocket client library
MIT License
692 stars 127 forks source link

Recursive calls in reconnection logic leads to memory leaks #124

Open Discolai opened 1 year ago

Discolai commented 1 year ago

Hi,

I am using this library in an application where a client might stay in a reconnection state over several days. The built in reconnection logic calls the WebsocketClient.StartClient method recursively. This leads to a steady increase in memory allocation after each reconnect attempt

The following code snippet creates 10 000 clients which reconnects every 100 milliseconds. It is not a real life scenario, but it demonstrates the issue. It managed to allocate 600MB in 30 sek

using Websocket.Client;

await Task.WhenAll(Enumerable.Range(0, 10_000).Select(i => CreateClient(i)).Select(client => client.Start()));

WebsocketClient CreateClient(int i)
{
    var websocketClient = new WebsocketClient(new Uri("ws://localhost:8080/ws"),  (_, _) =>
    {
        throw new Exception(i.ToString());
    })
    {
        ReconnectTimeout = TimeSpan.FromMilliseconds(100),
        ErrorReconnectTimeout = TimeSpan.FromMilliseconds(100),
        IsReconnectionEnabled = true
    };

    websocketClient.DisconnectionHappened.Subscribe(info =>
    {
        Console.WriteLine($"Disconnect - {info.Exception?.Message}");
    });
    return websocketClient;
}
Marfusios commented 1 year ago

Hey @Discolai ,

thank you for reporting this with the useful code snippet. I have broken the recursive call by introducing an error timer, and it seems to solve the problem nicely here: df2e007c103f248e2be3f4f35460a9033ad9469d

Before: image

After: image