RE: Resetting an Allegroserve worker process

"Cooper, Jock" <[email protected]> Mon, 1 Mar 2004 16:53:54 -0800
Newsgroups gmane.lisp.open-source.franz
Message-ID <[email protected]>
It is my understanding that process-kill is not safe to use.  The kill
could arrive during unwind actions which would terminate the process
before they complete.  

I am also using Allegroserve and running potentially long processes;  I
wound up using a cooperative means to shut down the long processes.  A
'master' thread can set a variable in the child thread using
PROCESS-INTERRUPT.   Periodically the child thread examines the variable
and then voluntarily exits if needed. This insures that any unwind
actions will always happen.

Furthermore, I do very little processing in the aserve thread.  If the
user presses refresh for example, he will get a *new* aserve thread
while the old one continues to run.  The old one will consume CPU until
it finishes whereupon its results are simply discarded. This can bog
things down fast.

The way I addressed this was as follows:

1. The Aserve thread identifies the user (using a session only cookie),
then checks to see if that user/browser already has a thread running.
If so, it asks that thread to shutdown (per PROCESS-INTERRUPT above).
Then the aserve thread starts a new child thread.  The aserve thread
does a PROCESS-WAIT on that new thread.  When finished the child thread
posts the computation results (eg a PDF or ZIP, or chunk of HTML, or nil
if it was asked to exit) and exits.  I used the MP QUEUE and GATE
structures for the communication between these threads.  The aserve
listener grabs the results and send them back down to the user.  (Or it
may do nothing if the child was shutdown).

If you are interested in seeing the code for this drop me a line.

John also replied that the browser will often resubmit the request.
That has been my experience as well.  Using something like I describe
above you could catch and prevent that also.

Hope this helps 
Jock Cooper

-----Original Message-----
From: [email protected] [mailto:[email protected]] On
Behalf Of JP Massar
Sent: Monday, March 01, 2004 12:34 PM
To: [email protected]
Cc: jeff Shrager; [email protected]
Subject: Resetting an Allegroserve worker process

Suppose that I have put an Allegroserve worker process into
an infinite loop, or it's doing some computation I decide to terminate.

Suppose the worker process I want to decommission is <p>.

The tests I've run using Allegro 6.2 on Windows with localhost
show the following behavior:

If I do an mp:process-kill on <p>, that destroys the worker process,
but restarts the computation using another worker process!

If I do an mp:process-reset on <p> the process resets, but it also
restarts
the computation.

There seems to be no way to just terminate and stop!

An example:

Let's say I have <p> performing the following computation deep inside
a servlet that <p> invokes to handle a particular published URL:

(dotimes (j 180) (sleep 1) (setq *foo* (list j (incf *xcount*)))

where I have independently setq'ed *xcount* to 0 previously.

So I can examine *xcount* from another thread, and of course its value
increases once a second.

Now if I do

(mp:process-kill <p>)

when, say *foo* = (60 61)

<p> goes away.  If I examine *foo* it looks something like (4 65).
If I examine it again it looks like, e.g., (6 67)

The list of processes shows that <p> (one of the worker processes)
is gone, but another one is running.

If I instead do

(mp:process-reset <p>)

the same kind of thing happens to *foo* but <p> does not go away.


Now, assuming I have not gone insane (because this behavior is quite
counterintuitive, especially wrt mp:process-kill) and this is indeed
what is happening, and assuming that I have no way of inserting
test code into my loop that is running in <p>, to test some dynamic 
termination flag, is
there any way I can just get the worker process to stop itself and
Allegroserve not to restart the computation?