delphiindywebbroker

Indy TCP server MaxConnections occasionally being ignored


I have a TWebModule (THireTrack_NX_API_Handler) that is being created via an Indy TIdHTTPWebBrokerBridge.

All seems to work as expected, only FWebBrokerBridge.MaxConnections seems to get ignored.

FWebBrokerBridge.IOHandler := LIOHandleSSL;
    SSLHelper := TSSLHelper.create;
    FWebBrokerBridge.OnQuerySSLPort := SSLHelper.QuerySSLPort;
    codesite.send('Listening Port', FPort);
    FWebBrokerBridge.DefaultPort := FPort; // default 10055
    FWebBrokerBridge.MaxConnections := FMaxConnections;
    FWebBrokerBridge.RegisterWebModuleClass(THireTrack_NX_API_Handler);
    FWebBrokerBridge.Active := True;

As a test, I set FWebBrokerBridge.MaxConnections to 1 and added a global counter to the OnCreate event of THireTrack_NX_API_Handler. I also decrement the counter in the OnDestroy of the same class.

I also added a codesite.Send('Max Connections Exceeded'); command to the DoMaxConnectionsExceeded(AIOHandler: TIdIOHandler); method.

I then used Postman to attempt to make 2 simultaneous connections (virtual users) continuously over the duration of 1 minute.

Mostly only 1 instance of THireTrack_NX_API_Handler existed and the MaxConnections exceeded message was logged as expected. However on a couple of occasions, 2 instances of THireTrack_NX_API_Handler existed.

I've rerun the tests setting MaxConnections to 10 and telling Postman to run as 50 virtual users and I get a max of around 24 instances of THireTrack_NX_API_Handler.

The number of instances isn't always growing, it goes up and down as instances are created and destroyed.

Have I done something wrong, or overlooked some setting somewhere, or am I just completely misunderstanding how this works?


Solution

  • I reviewed the server's source code, and the way the MaxConnections is currently implemented acts more like a hint than an absolute. It is possible to exceed the MaxConnections at times. I have opened a new bug ticket in Indy's GitHub repo for this issue:

    #632: TIdCustomTCPServer.MaxConnection can be exceeded at times

    Basically, when a new TCP client is accepted from a listening port, the server checks if adding that client to its Contexts list would exceed the MaxConnections, and if so then it disconnects the client immediately and calls DoMaxConnectionsExceeded(). Otherwise, the client continues on but is NOT added to the Contexts lists just yet. That happens at a later time after a worker thread is spun up to service the client. That thread adds the client to the Contexts list when the thread begins running.

    Which means, there is a small window of opportunity where if multiple clients connect to the server in a short amount of time, the MaxConnections may not be deemed as exceeded at the time of acceptance, but then will be exceeded once the threads begin running.