httpd-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Paul J. Reder" <>
Subject Re: Scoreboard redesign
Date Fri, 18 May 2001 01:52:05 GMT wrote:
> I am veto'ing the side effect of not allowing mod_status to be enabled on
> a restart.

Then there is nothing to veto. That was a bad temporary hack suggested by me that
led this whole discussion down a rat hole. Issue vaporized.

>            I dislike the complexity that this whole thing is adding.
> Traversing an array for the current status of the server is very clean and
> elegant.  I do not believe that a linked list will be as clean.  I am not
> veto'ing the linked list, I just don't believe it will be as clean a
> solution.

You are quite right. A linked list is more complex than a fixed position array.

> I would prefer to see a solution that allows processes to be created with
> fewer threads than required.  In fact, that is probably the easiest
> solution to the whole problem.  Let the child process handle it.
> My understanding of the overall problem to solve, is that it is possible
> for a single thread in a child process to keep that process slot from
> being used for a new child.
> Divorce the threads from the process, and this problem goes away.  For
> example, take this scoreboard.
> PID     THREAD  STATUS          ...
> 10      1       WAITING         ...
> 10      2       WAITING         ...
> 10      3       BUSY            ...
          (^--- Table 1)

And what of the case where you have 50 threads and 7, 12, 32, 41, and 48
are all busy...?

> Now, assume we get a graceful restart request, the scoreboard goes first
> to:
> PID     THREAD  STATUS          ...
> 10              STOPING         ...
> 10              STOPING         ...
> 10      3       BUSY            ...
> This one child process could be busy for a while, but why not allow a new
> child process to start, so that the scoreboard becomes:
> PID     THREAD  STATUS          ...
> 11      1       STARTING        ...
> 11      2       STARTING        ...
> 10      3       BUSY            ...

...will you have the "10  X  Busy ..." scattered throughout the section
for 7, 12, 32, 41, and 48? This seems like a more confusing and complex
solution to me than a simple linked list design and seems more fraught
with potential problems.

> The child can keep track of how many threads have already been started,
> and once the last thread of PID 10 goes away, it can create the final
> thread, so that the scoreboard becomes
> PID     THREAD  STATUS          ...
> 11      1       WAITING         ...
> 11      2       WAITING         ...
> 11      3       STARTING        ...
> Now, we keep the array design, which allows for a very simple
> implementation that does not require any locking, and we get the ability
> to do a real restart.  I do not believe that it will be possible to create
> a linked list implementation without locking, because you will need to
> traverse the list, and elements will be allocated and freed on the fly.

Yes locking is required with a linked list. The locking is only done when
processes/workers enter or leave (which is not that often in cpu terms).
The problem that we are trying to resolve is the case where, in the threaded
mpm, each process has a small number of workers left finishing long requests.
In your array based solution you could end up with N processes occupying the
same fixed indexed space. For example, if threads_per_child = 5 you could get

10     1       BUSY      ...
11     2       BUSY      ...
12     3       BUSY      ...
13     4       BUSY      ...
14     5       BUSY      ...

In the linked list design, by returning the finished workers to the list
you can start a new process any time that you get threads_per_process number
of elements on the free list. This seems much easier to implement and understand.
You would not end up with an example like table 1 above because the waiting 
workers would have finished up and exited on their own (when max_requests_per_child
is hit) or would be reclaimed when the restart happens. So you would have:

10     3        BUSY      ...

Later you might end up with 

10     3        BUSY      ...      (Still being cleaned up...)

11     2        BUSY      ...      (Still being cleaned up...)

13     4        BUSY      ...      (Still being cleaned up...)

15     1        WAITING   ...      (Currently processing requests...)
15     2        BUSY      ...
15     3        BUSY      ...
15     4        BUSY      ...
15     5        WAITING   ...

> The only addition to the code needed to implement this design, is a second
> table, private to the parent, with the same number of elements as the
> scoreboard.  This array will be used to store the pids of processes that
> are actually dying.  Because the parent is the only thing to modify the
> array, there is no locking involved, and it allows, for two different
> processes to share one process space in the scoreboard, assuming that one
> of the processes is trying to die.

This seems like it (possibly) avoids locking, which shouldn't happen that often,
for a more complex system of multiple tables tracking co-existence of multiple
(potentially up to threads_per_process) processes within the same fixed
scoreboard space. The list, even with its locks, seems simpler to me.

Paul J. Reder
"The strength of the Constitution lies entirely in the determination of each
citizen to defend it.  Only if every single citizen feels duty bound to do
his share in this defense are the constitutional rights secure."
-- Albert Einstein

View raw message