Project

General

Profile

Feature #2696

[PATCH] support -i <secs> idle timeout option

Added by mackyle over 1 year ago. Updated 11 months ago.

Status:
Fixed
Priority:
Low
Assignee:
Category:
core
Target version:
Start date:
2015-12-03
Due date:
% Done:

100%

Missing in 1.5.x:
Yes

Description

After <secs> of no activity the server will initiate a graceful
shutdown. Defaults to off (0).

This is particularly useful with something like git instaweb
that continues to spawn new server processes automatically but
does not automatically stop them.

Patch file attached.

See also http://repo.or.cz/lighttpd/svnmirror/patches.git/commitdiff/476d2d78

Associated revisions

Revision 06b87dee (diff)
Added by gstrauss 11 months ago

[core] cmd line opt to shutdown after idle time limit (fixes #2696)

-i <secs> graceful shutdown after <secs> of inactivity

Option might be used with applications such as git instaweb.
While git instaweb does have command line options of its own
to [start,stop,restart], some may find it convenient to configure
git instaweb to start lighttpd with a default idle time limit,
after which lighttpd will gracefully shut itself down without
any further action from the user.

x-ref:
"[PATCH] support -i <secs> idle timeout option"
https://redmine.lighttpd.net/issues/2696
original request and patch submitted by mackyle. thx.

Revision 89379011
Added by gstrauss 11 months ago

lighttpd run modes for idle timeout, one-shot

lighttpd -i <secs> shutdown after idle time limit (fixes #2696)
lighttpd -1 handles single request on stdin socket (fixes #1584)

Merge branch 'feature-2696-idle-shutdown' into master

github: closes #43

History

#1 Updated by mackyle over 1 year ago

I have attached a cleaner version.

The old version tried to compensate for the ftruncate patch (#2695) failing to properly handle graceful shutdown, but now that that's been corrected with an updated version of that patch, this patch needs updating too.

The new version of this patch should now be independent of the ftruncate patch in #2695.

See also http://repo.or.cz/lighttpd/svnmirror/patches.git/commitdiff/adedac49

#2 Updated by mackyle about 1 year ago

The recent update of the ftruncate patch (#2695) changed some of the context lines for this patch.

And updated patch is attached.

See also http://repo.or.cz/lighttpd/svnmirror/patches.git/commitdiff/f0d14f4c

#3 Updated by gstrauss about 1 year ago

Can you avoid the extra calls to time() by setting the default time_t idle_timeout = INT_MAX?
Next, in the periodic jobs section

    if (min_ts != srv->cur_ts) {

you can check
    if (min_ts - server_activity > idle_timeout) timed_out = 1;

Also, set server_activity = srv->cur_ts when there is activity.
Then, the check in the event loop (in the critical path) is simply if (timed_out).

Lastly, maybe rename server_activity to last_active_ts?

#4 Updated by gstrauss about 1 year ago

@mackyle: would you review my comments and update the patch? Thanks.

#5 Updated by mackyle about 1 year ago

As far as I know, the source of truth for lighttpd is svn://svn.lighttpd.net/lighttpd and the maintainer of that is stbuehler.

I posted this patch because I use it and on the off chance it might be an interesting enhancement to the lighttpd maintainer. It is a rather odd, and it seems to me, somewhat limited use case and so I would not be surprised or upset if it never got picked up.

So, no, I am not inclined to spend any more time on this unless I see some indication from the maintainer that there's interest in picking this up.

I will note, in response to your comments above, that it is entirely incorrect to mix INT_MAX with time_t and any system that has a time() call that is in any way expensive is broken.

If you feel that strongly about the changes, please go ahead and attach an updated patch to this issue with your name on it -- I will not feel offended in any way if your version of the patch should end up getting picked up instead of mine.

#6 Updated by gstrauss about 1 year ago

Attached patch with the changes I suggested.

The only thing done on the critical path is to set last_active_ts = srv->cur_ts, a trivial assignment to a stack variable. Once a second, the idle timeout is checked.

Also added code to disable if server.max-workers is specified. When server.max-workers is specified in the config file (to a value other than 0), children that exit will just be restarted by the parent.

BTW:

it is entirely incorrect to mix INT_MAX with time_t

That's rather strongly worded. Do you have a reference? time_t is at least int-sized on any POSIX system.
http://pubs.opengroup.org/onlinepubs/009695399/basedefs/sys/types.h.html

time_t and clock_t shall be integer or real-floating types.

INT_MAX is merely a very large number that will fit in 31-bits (if 'int' is 32-bits), which I chose to avoid any potential issue with signed types. In any case, I chose not to use INT_MAX and retained the check for != 0 to flag idle timeout as being enabled.

#7 Updated by mackyle about 1 year ago

"added code to disable if server.max-workers is specified. When server.max-workers is specified in the config file (to a value other than 0), children that exit will just be restarted by the parent."

Good catch. That right there is reason NOT to apply any version of this patch submitted so far.

Having a command-line timeout option that only works sometimes (depending on the config file) is probably a bad idea.
Slightly better would be having the server fail with an error and refuse to start if -i is specified together with max-workers > 0 (which I think is easily addressable).
Even better would be to have -i just work, always.

As for INT_MAX and time_t, what if INT_MAX is 32767, time_t is a (32-bit) long and -i 36000 (ten hours) is requested? It breaks.

The killer application for a -i timeout option is a web server running on-demand using a stream wait inetd configuration with an exit on idle timeout enabled. But lighttpd does not (yet) support an inetd mode. If it did, it would be important that the -i option not be ignored even if a message is emitted to the log file about it.

#8 Updated by gstrauss about 1 year ago

Having a command-line timeout option that only works sometimes (depending on the config file) is probably a bad idea.
Slightly better would be having the server fail with an error and refuse to start if -i is specified together with max-workers > 0 (which I think is easily addressable).
Even better would be to have -i just work, always.

That could be achieved by having presence of -i override server.max-worker.

However, if launched from inetd, then inetd is listening on IP addresses and port.

Do you have something intermediate that inetd is spawning? If so, that intermediate program could start up lighttpd, if it detected that lighttpd was not running, and then could proxy to lighttpd, which might be listening on a named piped instead of a public inet IP addr. That intermediate program could even implement the idle timeout, allowing it to start lighttpd with whatever server.max-worker setting it desired.

I have not looked at inetd in years, but there is a possibility that someone has already written some of these features into some version of inetd somewhere.

Are you using your patch for anything besides personal use with git instaweb? That use case probably does not need server.max-workers set.

#9 Updated by gstrauss about 1 year ago

  • Status changed from New to Patch Pending
  • Priority changed from Normal to Low

Submitted pull request https://github.com/lighttpd/lighttpd1.4/pull/43
It'll be easier to make tweaks to the patch after feedback.

Based on my most recent comment above, I modified the patch to disable server.max-worker if the command line option idle timeout is set.

#10 Updated by gstrauss 12 months ago

  • Target version changed from 1.4.x to 1.4.40

#11 Updated by gstrauss 11 months ago

  • Status changed from Patch Pending to Fixed
  • % Done changed from 0 to 100

Also available in: Atom