1

I have a Perl web app served by Apache httpd using plain mod_cgi or optionally mod_perl with PerlHandler ModPerl::Registry. Recently the app encountered the error Script timed out before returning headers on some invocations and behaved differently afterwards: While some requests seemed to be processed successfully in the background, after httpd sent status 504 to the client, others didn't.

So how exactly behaves httpd AFTER it reached its configured timeout and sent the error to the client? The request/response cycle is finished now, so I guess things like KeepAlive come into play to decide if the TCP connections stays alive or not etc. But what happens to the running script in which environment, e.g. mod_cgi vs. mod_perl?

Especially in mod_cgi, where new processes are started for each request, I would have guessed that httpd keeps the processes simply running. Because all our Perl files have a shebang, I'm not even sure if httpd is able to track the processes and does so or not. That could be completely different with mod_perl, because in that case httpd is aware of the interpreters and what they are doing etc. In fact, the same operation which timed out using plain mod_cgi, succeeded using mod_perl without any timeout, but even with a timeout in mod_cgi at least one request succeeded afterwards as well.

I find this question interesting for other runtimes than Perl as well, because they share the concepts of plain mod_cgi vs. some persistent runtime embedded into the httpd processes or using some external daemons.

So, my question is NOT about how to get the error message away. Instead I want to understand how httpd behaves AFTER the error occurred, because I don't seem to find much information on that topic. It's all just about increasing configuration values and try to avoid the problem in the first place, which is fine, but not what I need to know currently.

Thanks!

Thorsten Schöning
  • 3,501
  • 2
  • 25
  • 46

1 Answers1

1

Both mod_cgi and mod_cgid set a cleanup function on the request scope to kill the child process, but they do it slightly different ways. This would happen shortly after the timeout is reported (a little time for mod_cgi to return control, the error response to be written, the request logged, etc)

mod_cgi uses a core facility in httpd that does SIGTERM, sleeps for 3 seconds, then does a SIGKILL.

covener
  • 17,402
  • 2
  • 31
  • 45
  • So my succeeding process was only lucky being in the 3 seconds interval? Is there any way to influence this cleanup function, besides rising the timeout? Maybe any further documentation, so I can get some background about mod_per as well? – Thorsten Schöning Jan 27 '16 at 18:00
  • 1
    It is not configurable in mod_cgi or mod_cgid. In the former, it is part of a watch-list for any kind of child process that needs to be killed after a timeout. The API between modules and this facility is apr_pool_note_subprocess. There is one call to this in mod_perl but I cannot tell if it's for routine script execution (my guess would be no because there should not even be a child process for mod_perl?) The process lifetime stuff is in APR, see above method and free_process_chain in srclib/apr/memory/unix/apr_pools.c – covener Jan 27 '16 at 18:30