Re: User abort/stop, modperl 2 and TCP FIN / RST?

André Warnier <[email protected]>
Newsgroups gmane.comp.apache.mod-perl
Message-ID <[email protected]>
Peter Valdemar Mørch wrote:
> Hi,
> 
> I'm trying to find out how to detect user hitting 'stop' aka 'abort'
> in modperl 2. I found documentation on how it works in modperl 1 (
> http://perl.apache.org/docs/1.0/guide/debug.html#Detecting_Aborted_Connections
> - short version: $r->print returns success and $r->connection->aborted
> tells whether user hit abort ).
> 
> However, I've tested the situation to be quite different in modperl 2:
> 
> When the user hits 'stop', the *second* $r->rflush() generates an exception
>> Apache2::RequestIO::rflush: (103) Software caused connection
> as long as ~ 100ms has passed between the two rflush-es.
> 
> Here is my understanding of what happens:
> 
> When the user hits 'stop' in the browser, the browser sends a TCP
> packet with the FIN flag set. Apache2/modperl doesn't react to that
> and $r->connection->aborted still returns false. A subsequent
> $r->print and $r->rflush works fine. Apache now sends whatever was
> printed to the browser. The browser now sends RST ("Hey, I really want
> to kill this connection!") to Apache and after that, $r->print still
> succeeds (returns true), but $r->rflush dies (because now the client
> has closed the socket hard). "Second" $r->rflush really means "the
> first $r->rflush after Apache received the client's 'RST' ", so if I
> issue many $r->print("foo"); $r->rflush() in quick succession they all
> pass. Around 100ms needs to pass between $r->rflush-es for the second
> $r->rflush to fail. If tested this with Firefox and Chromium.
> 
> So: After the user hits 'stop', the second $r->rflush (requiring a
> delay) generates an exception that can be used to determine that the
> user has hit 'stop'.
> 
> Have I understood this correctly? Is there any way I can get Apache to
> react to the first TCP FIN, and have $r->connection->aborted return
> true at that point? Or otherwise detect reliably when the user has hit
> 'stop' in modperl 2 without having to wait an additional
> server-client-server roundtrip time?
> 

Hi.
Just my two cent, maybe just to dampen your expectations a little bit.
This topic is probably as old as the WWW itself, and there just is no magic bullet here.
Think of the following :
The whole FIN, ACK, RST etc.. exchange concerns /one/ TCP connection, between your browser 
and whatever it is talking to directly.  For example, a HTTP proxy server, or a firewall.
And then, this proxy/firewall has /another/ TCP connection with the next node in the chain 
(which may be your webserver or still another intermediary, like a load-balancer e.g.).
And in-between, there are buffers and a lot of piping, and delays.
So, expecting your mod_perl script to be able to detect instantly when the user at the 
browser half a planet away presses the "stop" button, is /never/ going to be guaranteed.
I'm not saying that you cannot try to catch such a thing as early as possible.
But if your ultimate aim is to find a way where instant detection is guaranteed, then give 
it up.  It is just not possible, given how the Internet, and TCP/IP and HTTP work.
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.