views:

233

answers:

1

So lets say there's a server process that takes way too long. The client complains that it "times out."

Correct me if I'm wrong, but this particular timeout could have to do with apache's timeout setting, but not necessarily. I believe this to be the case because when testing the page in question we couldn't get it to time out reliably - mostly the browser would just spin for as long as it took.

The timeout setting would come into effect if there were issues with the connection to the client, as described in the documentation. But if the connection was fine, it would be up to the client to close the connection (I believe).

I assumed this also meant that if the client closed their browser, Apache would hit the timeout limit (in my case, 300 seconds), and kill the process. This doesn't seem to be the case.

Here's how I tested it:
I added a while loop to some code on the server:

too_long = 2000
tstart = time.time()
f = open('/tmp/timeout_test.txt', 'w')
while True:
    time.sleep(100)
    elapsed = time.time() - tstart
    f.write('Loop, %s elapsed\n' % elapsed)
    if elapsed > too_long:
        break

I then open the web page to launch that loop, and ran netstat on the server:

~$ netstat -np | grep ESTAB | grep apache
tcp        0      0 10.102.123.6:443        10.102.119.101:53519    ESTABLISHED 16534/apache2
tcp        0      0 127.0.0.1:60299         127.0.0.1:5432          ESTABLISHED 16534/apache2

(that's me at 10.102.119.101, the server is at 10.102.123.6)
I then closed my browser and reran that netstat line:

~% netstat -np | grep ESTAB | grep apache
tcp        0      0 127.0.0.1:60299         127.0.0.1:5432          ESTABLISHED 16534/apache2

My connection disappeared, but the server was still in the loop, I could confirm by running:

~% lsof | grep timeout
apache2   16534   www-data   14w      REG        8,1        0     536533 /tmp/timeout_test.txt

meaning the apache process still had that file open. For the next 2000 seconds, when I ran:

~% cat /tmp/timeout_test.txt

I got nothing. After 2000 seconds the netcat line produced nothing at all, and the tmp file was filled out with the output from the while loop.

So it seems that Apache process just does what it was asked to do, regardless of the client connection? And what is that loopback connection about?

+1  A: 

Correct. In a C apache module you can add a check like:

/* r is the 'request_rec' object from apache */
if (r->connection->aborted) {
    /* stop processing and return */
}

to verify that the client is still connected. Probably the python interface has something similar.

As for the loopback connection, it is a connection to a postgresql database kept open for as long as that loop is running.

Gonzalo
right, postgres! I should've noticed port 5432so basically it's up to the Apache interface I'm using to decide if it should kill an aborted process?
EMiller
Yes, but there has to be a way in which mod_wsgi can relay that information to your python code.
Gonzalo
hmh, I'm not sure why mod_wsgi needs to relay that info to my python code? Can't mod_wsgi just kill the process? From looking at the mod_wsgi source, it should be logging the event: http://code.google.com/p/modwsgi/source/browse/trunk/mod_wsgi/mod_wsgi.c#3263 but I'm not finding it in any of my logs. Shouldn't that event trigger at the end of whatever Apache Timeout is set to? (5 min by default)
EMiller
That code you point out is never reached because your program never returns. Apache will first try politely and then just kill -9, which will prevent the output sending code from executing.
Gonzalo