SocketStream>>flush question
C. David Shaffer
cdshaffer at acm.org
Mon Mar 8 14:56:15 UTC 2004
Yoshiki Ohshima wrote:
>
> But, you, err, the user of Socket, have to take care of the error
>conditions accordingly. The low-level code (Socket and SocketStream)
>cannot know what would be the right thing to do on errors because it
>is application specific.
>
>
That is the case generally but the problem I'm having is that
SocketStream>>close sends flush so it is the "user" of the Socket. The
close should succeed even if the data can't be flushed (in my opinion)
since it leaves you in a sticky mess if you can't close the socket. I
guess that you could expect the caller to protect the close:
[socketStream close] ensure: [socketStream socket isOpen ifTrue:
[socketStream socket close]]
but this seems a little silly. I propose a change (below) to
SocketStream>>close and flush that make them more useful at the
application level. Please, if I'm wrong here just let me know...show me
code to close a SocketStream which ensures that the socket is really closed.
> There is no guard predicates to ensure the subsequent #sendData: or
>such succeeds as the socket status can be changed after the guard test
>and before #sendData:. So, the 'fix' to the guard predicate in
>SocketStream>>flush won't 'fix' the whole situation.
>
>
Yes, you're right about that. It makes me wonder why there is any
"guard" at all. It just makes the SocketStream API more confusing
(throws an exception _if_ the connection is closed but the close hasn't
been detected yet). You've pretty much convinced me that the best
solution is something like this (in SocketStream):
flush
"Flush buffered data to socket. Throws exception if data cannot be
sent."
self socket sendData: self outStream contents.
self resetOutStream
close
"Attempts to #flush then closes socket. Exceptions on flush or
close will be passed up but the close is always attempted."
[self flush] ensure: [self socket closeAndDestroy: 30]
The usage pattern becomes:
[socketStream close] on: NetworkError do: [:ex | "handle data
transmission error and/or close error if you like"].
Then the various Socket method would have to be changed to throw the
various subclasses of NetworkError (filling in gaps where they exist).
What do you think?
>
> What I'd do is to handle the ConnectionTimedOut exception and the
>other kind of exception differently if needed.
>
>
Yes, usually that would be appropriate. What I'm proposing is having
"other kind of exception" be subclasses of NetworkError and leave "self
error: 'primitive failed'" for cases when a primitive fails due to a
non-sockets I/O related problem.
> I'm curious what kind of different actions we could take for
>different type of errors.
>
>
I don't have an answer for that. At the moment I simply need a
reasonable way to close a SocketStream which requires better error
support in Socket. Maybe these other "actions" will come up as this
code evolves...?
David
--
C. David Shaffer
http://www.cs.westminster.edu/~shaffer
http://www.shaffer-consulting.com
More information about the Squeak-dev
mailing list
|