delphirules
delphirules

Reputation: 7438

TIdHTTPServer and 100% CPU usage

I use TIdHTTPServer in Delphi 11 to run a simple web server on a VPS.

It works great, except from time to time my app will start to use 100% of the CPU and keep this way forever, and I can't identify what is causing this.

When this happens, the server is still active and replying to requests, but very slowly. The only way to fix this is to force close the application and open it again.

I don't have any code to show, as my code is just generic responses using the OnCommandGet event of the TIdHTTPServer. This event will handle GET parameters on the URL and return something in the AResponseInfo.ContentText.

I know this is difficult, but any ideas about what I should hunt for to fix this?

Upvotes: 0

Views: 381

Answers (1)

Softacom
Softacom

Reputation: 643

We use TIdHttpServer quite a lot and have no problems with it. We use it in Delphi 10.3-10.4.2, but it’s not the reason for the problem. Programs work a few months without restarting.

From our experience we can say that problem of such unexpected behavior can be (in order of probability):

  • Code is not threadsafe. Event OnCommandGet run not in a main thread, so all access to global object/resources/etc must be done thru some kind of synchronization mechanism (locks, TEvent, synchronize, mutex, semaphore or other). If code does not use synchronization – it can broke logic, throw exceptions or do some other unexpected actions (like high CPU usage).
  • Connections count go over the limit. TIdHttpServer has properties like ListenQueue and MaxConnections. Can be that you make more requests that the server can handle. In this case your new requests wait until they can be handled by your code and it can make some additional CPU usage. To diagnose this – try to increment some internal variable at the start of your event and decrement it at the end. Make some service request to return this variable and you will know if all work correctly. Other similar situation – connection does not close after using the inside event and stay in memory, then you can go over limits too. Try to workaround properties TIdHttpServer.KeepAlive := false and TIdHttpServer.ReuseSocket := rsFalse.
  • Memory leaks. Try to set variable ReportMemoryLeaksOnShutdown := true and start the application, make a few requests and close it. If you’ll see a message with leaks – then you do something wrong, try to handle these objects in the right way. In production these small leaks can take a lot of RAM and Windows will dump part of memory into a swap-file, so your new requests will take more time to be processed.

Without an example, we can't say more.

Upvotes: 5

Related Questions