[Zope-dev] [BUG] Background processes interfere with Zope's HTTP responses
Dieter Maurer
dieter@handshake.de
Tue, 19 Dec 2000 20:53:44 +0100 (CET)
Today was again a hard Zope day.
Did you ever hear, that usually (i.e. if you do not do special
things) Zope renders a complete page before it starts
sending the result back to the client.
This implies that you should never see only half of a page.
I heard it and I saw the code that does it.
Therefore, I was convinced that this were really the case.
Then our client phoned:
He visits a page that allows him to generate a
newsletter. When he presses the "generate newsletter button",
a result page is build that tells him that the newsletter
is being generated and send is a few minutes.
He reported, that this response page is build only
half, then stops, to be completed only half a minute later,
at the same time when the newsletter arrives.
The effect is reproducible. If newsletter generation
takes longer, he must wait longer for the page to complete.
He is convinced that we generate the newsletter synchronously
and let him wait until the generation is complete.
And he is angry.
I know, that the newsletter is generated in a background
process, started in an external method with:
os.system("gen_newsletter &")
I try to reproduce the behaviour in our test environment
and fail. I do not have to wait, until the newsletter
generation finished. Then, I use the official service
URL and see, I observe the same behaviour.
The difference: in the test environment, the browser
connects directly to ZServer; with the official
URL, it connects via a proxy.
Puzzling!
What happened?
The background process inherits Zope's open file descriptors.
Among them are all currently open HTTP request sockets.
The process keeps these sockets open until it finishes.
There are two HTTP modes:
1. single request mode
a new TCP connection is created for each HTTP request,
the request is completed, when the TCP connection
is closed.
2. multi request mode
several requests share a single TCP connection.
The "Content-Length" HTTP header allows
client and server to determine the request boundaries.
That means: when a client uses the multi request mode,
everything is fine. Clients, however, that use
the single request mode wait until their connection
is closed and can observe serious delays.
These delays may be very difficult to explain, as
the background process not only delays its own
request but may delay arbitrary other requests
that happen to be served at the same time.
How to fix the problem:
There should be a (file) control "CloseOnExec", that tells
Unix to automatically close the file like object upon
an exec.
ZServer should probably use it on each of its sockets.
I can not see a serious application that should have
direct access to ZServer's HTTP request socket.
I will soon file a bug report into the Collector.
Dieter