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?
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.