This one is actually fixed in the Comanche changeset.  I think there are
some other Squeak fixes in there as well, that just never got separated
out and sent to Squeak Central.

In fact, as far as I can tell, the delay has been turned back up to 20
or 30 seconds in the Comanche distribution.  But I could be reading it wrong. 
Best would be to find a server with the problem and put some debugging
printouts to see what's really happening.  Is closeAndDestroy: being
called with a reasonable timeout?  What is the state of the socket when
the closeAndDestroy: finishes?

By the way, saving the FAQ page on the Squeak wiki seems to have this
problem every single time....


Lex




Bob Arning  <[EMAIL PROTECTED]> wrote:
> On Sun, 5 Mar 2000 13:54:45 "Lex Spoon" <[EMAIL PROTECTED]> wrote:
> >Actually, I've seen this on minnow, which (I think) is a 300-400MHz G3
> > If you save a large page, then the socket seems to get closed before
> >all the data comes back.  The page actually does get saved, but the
> >client doesn't get to see it.  That's why saving it a second time would
> >generate an edit conflict.
> >
> >This problem would be worse on faster servers, because they can close
> >the socket faster :)
> >
> >Overall,  closeAndDestroy: is supposed to avoid this problem.  I
> >remember at one time that the delay was turned way down in
> >closeAndDestroy: in Comanche.  Is that currently the case in
> >Comanche/ComSwiki?
> 
> This may be related to the problem observed last year when saves in quick succession 
>seemed to hang some servers. It may be that the timeout was reduced so that the 
>socket would likely be destroyed before the second save arrived, thus avoiding he 
>hang. Unfortunately, this could prematurely terminate the data being sent (actually, 
>that could happen with any timeout value since a slow/noisy network could 
>legitimately take a long time send all the data). If the timeout was reduced to fix 
>the hang, it might be better to fix the hang and restore the timeout to a healthier 
>value. Enclosed is a changeset that seemed to fix the problem.
> 
> Cheers,
> Bob
> 
> 'From Squeak2.8alpha of 13 January 2000 [latest update: #1873] on 5 March 2000 at 
>4:04:54 pm'!
> "Change Set:          socketClose
> Date:                 5 March 2000
> Author:                       Bob Arning
> 
> There can be a problem trying to close a socket while there is still unread data 
>available. On the Mac, the close may need to timeout and a second request during that 
>time may hang the machine altogether. How this affects other OS is unclear. As to why 
>dataAvailable is an issue:
> 
> 1. Squeak actually has code that *almost* gets it right.
>       Socket>>closeAndDestroy: sends self waitForDisconnectionUntil: ...
>       Socket>>waitForDisconnectionUntil: tries to read any data that comes in after 
>the close using self discardReceivedData.
>       Socket>>discardReceivedData will _only_ read the data if the socket is 
>Connected, but by this time the socket is ThisEndClosed and the data is ignored.
> 
> I made a change so that Socket>>discardReceivedData reads data in either Connected 
>or ThisEndClosed status and was able to continuously edit/save/etc. This would appear 
>to be a more robust approach than the one I previously suggested, but if you adopt 
>this approach, you will probably want to deal with the self inform: in 
>Socket>>waitForDisconnectionUntil: in a less intrusive manner.
> 
> 2. It is curious why saving short pages seems to leave no unread data, but saving 
>long pages leaves a CRLF unread. Who decides when to stop reading data from the 
>socket? And how?
> 
> 3. For the terminally curious, here is an excerpt from the MacTCP docs that explains 
>the close a bit more fully than I had previously understood:
> =============================
> Connection closing
> TCP closes communications gracefully. All outstanding Send requests are transmitted 
>and acknowledged before the connection is allowed to close. You can issue several 
>TCPSend commands followed by a TCPClose command and expect that all the data will be 
>sent successfully to the remote TCP. 
> A TCPClose command means �I have no more data to send,� but it does not mean �I will 
>receive no more data� or �shut down this connection immediately.� A connection may 
>remain open indefinitely as the remote TCP continues to send data after a TCPClose 
>command has been completed. When the remote TCP also issues a close command�and only 
>then�the connection is closed. A TCPRcv command should be issued after a TCPClose 
>command has been completed to make sure that all the data is received.
> If the desired effect is to break the connection without any assurance that all data 
>in transit is delivered, use the TCPAbort command.
> 
> ==================
> "!
> 
> 
> !Socket methodsFor: 'queries' stamp: 'RAA 3/5/2000 16:03'!
> isConnectedOrThisEndClosed
>       | status |
>       "Return true if this socket is connected OR has been closed at this end only."
> 
>       socketHandle == nil ifTrue: [^ false].
>       status _ self primSocketConnectionStatus: socketHandle.
>       ^status == Connected or: [status == ThisEndClosed]
> ! !
> 
> !Socket methodsFor: 'sending-receiving' stamp: 'RAA 10/21/1999 10:58'!
> discardReceivedData
>       "Discard any data received up until now, and return the number of bytes 
>discarded."
> 
>       | buf totalBytesDiscarded |
>       buf _ String new: 10000.
>       totalBytesDiscarded _ 0.
>       [self isConnectedOrThisEndClosed and: [self dataAvailable]] whileTrue: [
>               totalBytesDiscarded _
>                       totalBytesDiscarded + (self receiveDataInto: buf)].
>       ^ totalBytesDiscarded
> ! !

Reply via email to