HTTP.hs with slow execution

Jens Petersen juhp@01.246.ne.jp
09 Jun 2002 22:40:14 +0900


Hi Warrick,

Thanks for your reply.

"Warrick Gray" <oinutter@hotmail.com> writes:

> [redirecting to haskell-cafe]

[from the libraries list incidently]

> >I think I found an issue with the HTTP.hs library when
> >making a short-lived non-persistent connection to a server
> >from a slower machine (i486).  I can also reproduce it by
> >running my program with strace or ltrace on a faster machine
> >(PIII).
> 
> >recvfrom(3, 0x500a2008, 1000, 0, 0x500a23f8)      = 0
> >getpeername(3, 0x500a241c, 0x500a2434, 0x080dfda0, 1) = 0
> 
> After no data is received the sending part of the TCP stream is closed:
> >shutdown(3, 1, 0x0805b85f, 0x080e018c, 1)         = 0
> 
> Being polite, the library ensures that all incoming data has
> been consumed, forgetting for a moment that the incoming
> stream has already closed:
> 
> >recvfrom(3, 0x500a2440, 1000, 0, 0x500a2830)      = 0
> >getpeername(3, 0x500a2854, 0x500a286c, 0x080e018c, 1) = -1
> 
> The "recvfrom" seems fine, the "getpeername" call comes from
> the definition of Network.Socket.recvFrom, which features:
> 
> 	flg <- sIsConnected sock
> 	  -- For at least one implementation (WinSock 2), recvfrom() ignores
> 	  -- filling in the sockaddr for connected TCP sockets. Cope with
> 	  -- this by using getPeerName instead.
> 	sockaddr <-
> 		if flg then
> 		   getPeerName sock
> 		else
> 		   peekSockAddr ptr_addr
> 
> ...Leading to the error in question:
> > strerror(107)                                     =
> > "Transport endpoint is not connec"...
> 
> The answer I guess is to alter all calls to 'recvFrom' to
> 'recv' calls (done),

Thanks, this helps, but now it fails for me sometimes
(consistently on my slow machine) at the shutdown for the
read side.  Below is the tail of the strace output.

BTW, wow!  I didn't realise the implementation was so low
level.  There's no way to avoid that and get a faithful
implementation, presumably?

> or replace socket reference with ConnClosed at the first
> sign of a closed socket.

Sounds like this would probably solve the problem.

> Unfortunately the second will have to wait, but the first
> is implemented and available in the latest version:
> http://homepages.paradise.net.nz/warrickg/haskell/http

Cheers, Jens


recv(3, "", 1000, 0)                    = 0
shutdown(3, 1 /* send */)               = 0
recv(3, "", 1000, 0)                    = 0
shutdown(3, 0 /* receive */)            = -1 ENOTCONN (Transport endpoint is not connected)
ioctl(1, SNDCTL_TMR_TIMEBASE, {B38400 opost isig icanon echo ...}) = 0
--- SIGVTALRM (Virtual timer expired) ---
sigreturn()                             = ? (mask now [])
fcntl(2, F_GETFL)                       = 0x8001 (flags O_WRONLY|O_LARGEFILE)
write(2, "\nFail: ", 7
Fail: )                 = 7
write(2, "invalid argument\nAction: shutdow"..., 78invalid argument
Action: shutdown
Reason: Transport endpoint is not connected
) = 78
write(2, "\n", 1
)                       = 1
_exit(1)                                = ?