[ENH] FastSocketStream-gk
Willem van den Ende
squeak at willemvandenende.com
Wed Feb 16 10:23:11 UTC 2005
On Tuesday 15 February 2005 20:43, goran.krampe at bluefish.se wrote:
> Hi!
>
> Willem van den Ende <squeak at willemvandenende.com> wrote:
> > Hi Göran,
> >
> > cool that someone is working on this! Maybe the new FastSocketStream can
> > solve a problem I've been having...
>
> Hope so too. :)
>
>
> Right, the old SocketStream (as I painstakingly describe in the very
> long class comment) swallows exceptions - which IMHO was bad design. You
> can get the same behavior with FSS if you send it "shouldSignal: false"
> but then lots of methods will not honour the timeout (they are carefully
> marked in the method comments, and the class comment describes that
> too). Which is actually the same behavior as the old SocketStream has -
> which also SocketStreamTest verified.
from the class commment:
"The reason for SocketStream to fail is that while it does timeout on a low
level (#SocketStream>>receiveData doesn't hang forever) - the callers of
#receiveData sometimes loop - like in #next:, and thus eliminates the
timeout. "
I guess the SWHttpClient may need changing. It has its own timeoutloop, am I
correct in assuming timeout handling would be better handled only by
FastSocketStream? As it is now, it looks like a deadlock waiting to
happen.... (which might explain the image lockups) (accidentally you can see
the 'timeoutloop' variable in the bottom of the stacktrace).
If so, the http client code could be much simpler - call #upToEnd and don't
bother doing more difficult stuff. By the way, the code in FastSocketStream
does look simple and understandable :-). Time for more code in the image to
follow this example.
>
> So it is not the Right Thing to turn off the signals. The Right Thing
> would be to catch the ConnectionClosed and handle it. The only method
> that actually catches ConnectionClosed is #upToEnd because it
> intrinsically must catch it - otherwise it makes very little sense. :)
>
> The failed primitives I have no idea about. Do you have any more info on
> that?
I've had them before. It may be the way SWHttpClient deals with sockets. I put
a halt in where it might occur. I'll send a stacktrace and save the image
away to answer any questions you might have. I'm currently waiting for one to
occurr... Wait. While I was writing this it happened. I added a lengthy
stacktrace below (MethodContext reportErrorOn: with 5 levels is not really
enough to see anything about what's going on). If you need more info, let me
know.
>
> > I'm using a 3.7 image with a /3.7b-5 VM from ian pumarta's site. I used
> > an older vm as well, with the same problems.
>
> Ok. Well, I use that VM too, haven't seen any real problems - but I am
> not running a spider so... :)
Under windows the lockups happen as well. Looking at the http client code, I
suspect making the simplification using FastSocketStream #upToEnd might make
the problem disappear. I should have been warned... the SqueakMap comment for
SWHttpClient said that cleanup work is needed. I'll see what I can do about
it later this week.
>
> > The good news is, the FastSocketStream does seem to be faster on sites
> > that are not slow, and I hope it doesn't lock anymore...
>
> Well, that is why I call it FastSocketStream :). It IS faster. The
> implementation is carefully designed to use faster primitives and much
> less copying.
the code looks carefully made!
cheers,
Willem.
>
> > I hope this helps. Keep up the good work!
>
> Thanks, Göran
Stacktrace:
Socket(Object)>>error:
Receiver: a Socket[destroyed]
Arguments and temporary variables:
aString: 'a primitive has failed'
Receiver's instance variables:
semaphore: nil
socketHandle: nil
readSemaphore: nil
writeSemaphore: nil
primitiveOnlySupportsOneSemaphore: false
Socket(Object)>>primitiveFailed
Receiver: a Socket[destroyed]
Arguments and temporary variables:
Receiver's instance variables:
semaphore: nil
socketHandle: nil
readSemaphore: nil
writeSemaphore: nil
primitiveOnlySupportsOneSemaphore: false
Socket>>primSocketReceiveDataAvailable:
Receiver: a Socket[destroyed]
Arguments and temporary variables:
socketID: nil
Receiver's instance variables:
semaphore: nil
socketHandle: nil
readSemaphore: nil
writeSemaphore: nil
primitiveOnlySupportsOneSemaphore: false
Socket>>waitForDataFor:ifClosed:ifTimedOut:
Receiver: a Socket[destroyed]
Arguments and temporary variables:
timeout: 45
closedBlock: [] in Socket>>waitForDataFor: {[ConnectionClosed signal:
'Connecti...etc...
timedOutBlock: [] in Socket>>waitForDataFor: {[ConnectionTimedOut signal:
'Data...etc...
deadline: 1956532
Receiver's instance variables:
semaphore: nil
socketHandle: nil
readSemaphore: nil
writeSemaphore: nil
primitiveOnlySupportsOneSemaphore: false
Socket>>waitForDataFor:
Receiver: a Socket[destroyed]
Arguments and temporary variables:
timeout: 45
Receiver's instance variables:
semaphore: nil
socketHandle: nil
readSemaphore: nil
writeSemaphore: nil
primitiveOnlySupportsOneSemaphore: false
Socket>>receiveDataSignallingTimeout:into:startingAt:
Receiver: a Socket[destroyed]
Arguments and temporary variables:
timeout: 45
aStringOrByteArray: '-calendar-day-nolink Monday">18</td>
<td class="month-cale...etc...
aNumber: 4718
Receiver's instance variables:
semaphore: nil
socketHandle: nil
readSemaphore: nil
writeSemaphore: nil
primitiveOnlySupportsOneSemaphore: false
FastSocketStream>>receiveData
Receiver: FastSocketStream[inbuf:16kb/outbuf:4kb]
Arguments and temporary variables:
Receiver's instance variables:
recentlyRead: 1573
scs: 0
rcs: 22
socket: a Socket[destroyed]
inBuffer: '-calendar-day-nolink Monday">18</td>
<td class="month-calendar-day-n...etc...
outBuffer: 'GET /index.cgi/2004/10/%23top HTTP/1.1
accept: text/html
host: ce...etc...
inNextToWrite: 4718
outNextToWrite: 1
lastRead: 0
timeout: 45
autoFlush: true
bufferSize: 4096
binary: false
shouldSignal: true
FastSocketStream>>receiveData:
Receiver: FastSocketStream[inbuf:16kb/outbuf:4kb]
Arguments and temporary variables:
nBytes: 1024
needToGet: 15805
Receiver's instance variables:
recentlyRead: 1573
scs: 0
rcs: 22
socket: a Socket[destroyed]
inBuffer: '-calendar-day-nolink Monday">18</td>
<td class="month-calendar-day-n...etc...
outBuffer: 'GET /index.cgi/2004/10/%23top HTTP/1.1
accept: text/html
host: ce...etc...
inNextToWrite: 4718
outNextToWrite: 1
lastRead: 0
timeout: 45
autoFlush: true
bufferSize: 4096
binary: false
shouldSignal: true
FastSocketStream>>next:
Receiver: FastSocketStream[inbuf:16kb/outbuf:4kb]
Arguments and temporary variables:
anInteger: 1024
start: nil
Receiver's instance variables:
recentlyRead: 1573
scs: 0
rcs: 22
socket: a Socket[destroyed]
inBuffer: '-calendar-day-nolink Monday">18</td>
<td class="month-calendar-day-n...etc...
outBuffer: 'GET /index.cgi/2004/10/%23top HTTP/1.1
accept: text/html
host: ce...etc...
inNextToWrite: 4718
outNextToWrite: 1
lastRead: 0
timeout: 45
autoFlush: true
bufferSize: 4096
binary: false
shouldSignal: true
SZReadWriteSocketStream>>nextBytes:
Receiver: a SZReadWriteSocketStream
Arguments and temporary variables:
anInteger: 1024
Receiver's instance variables:
readStream: FastSocketStream[inbuf:16kb/outbuf:4kb]
writeStream: FastSocketStream[inbuf:16kb/outbuf:4kb]
SptHTTPResponse>>readContentLengthBody:
Receiver: a SptHTTPResponse
Arguments and temporary variables:
aConnection: a SptHTTPConnection
total: 8813
read: 4096
bytes: 1024
Receiver's instance variables:
statusLine: 'HTTP/1.1 200 Ok'
headers: a PluggableLookupTable('cache-control'->'no-cache'
'content-length'->'...etc...
bodyStream: a WriteStream a ByteArray(60 104 116 109 108 62 10 60 104 101
97 10...etc...
request: a SptHTTPRequest
SptHTTPResponse>>readMessageBody:
Receiver: a SptHTTPResponse
Arguments and temporary variables:
aConnection: a SptHTTPConnection
Receiver's instance variables:
statusLine: 'HTTP/1.1 200 Ok'
headers: a PluggableLookupTable('cache-control'->'no-cache'
'content-length'->'...etc...
bodyStream: a WriteStream a ByteArray(60 104 116 109 108 62 10 60 104 101
97 10...etc...
request: a SptHTTPRequest
SptHTTPResponse>>readResponse:
Receiver: a SptHTTPResponse
Arguments and temporary variables:
aConnection: a SptHTTPConnection
startT: nil
Receiver's instance variables:
statusLine: 'HTTP/1.1 200 Ok'
headers: a PluggableLookupTable('cache-control'->'no-cache'
'content-length'->'...etc...
bodyStream: a WriteStream a ByteArray(60 104 116 109 108 62 10 60 104 101
97 10...etc...
request: a SptHTTPRequest
SptHTTPRequest>>readResponse
Receiver: a SptHTTPRequest
Arguments and temporary variables:
response: a SptHTTPResponse
Receiver's instance variables:
connection: a SptHTTPConnection
url: a SptHTTPUrl
method: 'GET'
headers: a PluggableLookupTable('accept'->'text/html' 'host'->'cepslog.com'
'us...etc...
responses: an OrderedCollection(a SptHTTPResponse)
entity: nil
deferredSend: [] in SptHTTPRequest>>send {[self sendMessages]}
okBodyStream: a WriteStream a ByteArray(60 104 116 109 108 62 10 60 104 101
97 ...etc...
state: a SptHTTPSessionState
flags: 13
progress: a SptHTTPProgress
conf: a SptHTTPConfiguration
timeoutLoop: a Process in Delay>>wait
More information about the Squeak-dev
mailing list
|