[prev in list] [next in list] [prev in thread] [next in thread] 

List:       apache-modperl
Subject:    Re: mod_perl and Apache::DBI - what happens on request termination
From:       Torsten =?ISO-8859-1?Q?F=F6rtsch?= <torsten.foertsch () gmx ! net>
Date:       2012-06-05 11:29:50
Message-ID: 1537370.lvCJLNM4XR () opi ! home
[Download RAW message or body]

On Tuesday, 05 June 2012 10:52:54 Erik Scholtz wrote:
> thanks for your answer, which confirms my observation on this: Do you 
> have documents that will explain this behaviour in detail?

Simple explanation, you have a single thread of execution. It can either block 
on the database or watch for events on the client socket.

I assume you want to abort the database transaction if the client closes the 
socket. This can possibly be achieved if the client isn't sending the next 
request over the same connection before the reply for the first has been 
received. However, I haven't done this yet.

First, get the file descriptor of the client socket. See
http://perl.apache.org/docs/2.0/api/Apache2/Connection.html#C_client_socket_
http://perl.apache.org/docs/2.0/api/APR/Socket.html#C_fileno_

Note, the $c->aborted flag isn't of any use here. It is set only when the 
socket is written to by the core output filter. Also, APR::Socket::fileno 
works only on UNIX-like systems where the file descriptor is a number.

Then obtain the file descriptor of the database handle. For example, if you 
are using PostgreSQL DBD::Pg provides it as $dbh->{pg_socket}.

Now, start the transaction asynchronously. See "Asynchronous Queries" in the 
DBD::Pg manual.

Read the request body. If in doubt call $r->discard_request_body.

Then you can watch both file descriptors by means of select(2) or similar (I 
prefer AnyEvent here). If it returns with the client socket ready try to 
recv(2) from it with the MSG_PEEK flag set. If it returns no error the client 
has sent additional data, probably the next request. In this case you have to 
complete the database transaction because even if the client aborts the 
connection afterwards it is not knowable until you read the data. If recv(2) 
returns with an error cancel the DB transaction.

If select(2) reports the DB connection ready handle it.

That's the way I'd try it.

Torsten Förtsch

-- 
Need professional modperl support? Hire me! (http://foertsch.name)

Like fantasy? http://kabatinte.net

[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic