perl-modperl mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Randolf Richardson" <rand...@modperl.pl>
Subject Re: User abort/stop, modperl 2 and TCP FIN / RST?
Date Mon, 11 Jun 2012 16:39:06 GMT
> 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.

	In addition to that, there is variation among web browser and smart 
phone vendors in the way they tear down sockets.  Some may close the 
socket immediately (a good practice in my opinion), while others may 
just let the resource get garbage collected or even have an unknown 
bug that results in a temporary or permanent resource leak on the 
client-side.

	The same problems can occur with proxy servers, and for localized 
end-user products that intercept all traffic (e.g., for the purpose 
of scanning for viruses or other suspicious activity) there can be 
problems as well.  I've seen big problems with long timeouts with 
some of these client-side products where the server has lingering 
connections after the QUIT phase with POP3 connections, and removing 
the firewalling software resolved the problem (but this isn't a 
solution that helps you because many users insist on running these 
programs, are working at companies that require it, etc.).

	Making sure you have adequate resources to handle the load on the 
server-side is likely less time-consuming than figuring out how every 
web browser does (and will) handle the user pressing the "Stop" 
button behind-the-scenes, although the KeepAlive and KeepAliveTImeout 
directives may be helpful to you:

		http://httpd.apache.org/docs/current/mod/core.html#keepalive
		http://httpd.apache.org/docs/current/mod/core.html#keepalivetimeout

	Note:  The KeepAliveTimeout directive is only available starting 
with Apache HTTPd v2.3.2.

	Have you've already experimented with the Timeout directive?  If 
not, then I suggest you start with this directive before using the 
KeepAlive and KeepAliveTimeout directives:

		http://httpd.apache.org/docs/current/mod/core.html#timeout

Randolf Richardson - randolf@inter-corporate.com
Inter-Corporate Computer & Network Services, Inc.
Beautiful British Columbia, Canada
http://www.inter-corporate.com/



Mime
View raw message