On 14 Jan 2011, at 12:54, Schwab,Wilhelm K wrote:

> I am really bothered by the timeout on the accept, so much so that I think it 
> has no place in the tests.  Of course, one needs a way to clean up after a 
> failure, but that should be done by another thread that waits for a "long" 
> time and then cleans up anything that is left behind after the failure.
> 
> Servers should be started and stopped and in between, they should wait for 
> and accept connections.  Clients should try to connect until told otherwise; 
> timeouts can be reasonable options there, but should not be forced by the 
> sockets system.  Only the calling threads should be blocked, of course.


I don't understand why this would bother you: it is the 'client/user' that 
decides about the timeout (you could use some very large number for an 
'infinite' timeout). You need of course a loop around it. Here is the code from 
ZnSingleThreadedServer (which started from the Blackfoot example):

listenLoop
        "We create a listening Socket, then wait for a connection.
        After each connection we also check that the listening Socket is still 
valid 
        - if not we just make a recursive call to this method to start over."

        self initializeServerSocket.
        [ [ 
                serverSocket isValid
                         ifFalse: [
                                "will trigger #ifCurtailed: block and destroy 
socket"
                                ^ self listenLoop ].
                self serveConnectionOn: serverSocket ] repeat ]

                ifCurtailed: [ self releaseServerSocket ]

serveConnectionOn: listeningSocket
        "We wait up to acceptWaitTimeout seconds for an incoming connection.
        If we get one we wrap it in a SocketStream and 
#executeOneRequestResponseOn: on it"
                 
        | stream socket |
        socket := (listeningSocket waitForAcceptFor: self acceptWaitTimeout) 
ifNil: [
                ^ self log: 'Wait for accept timed out' ].
        stream := ZnNetworkingUtils socketStreamOn: socket.
        [ [ [ self executeOneRequestResponseOn: stream ]
                ensure: [ self log: 'Closing stream'. stream close ] ]
                        ifCurtailed: [ self log: 'Destroying socket'. socket 
destroy ] ]
                                forkAt: Processor highIOPriority
                                named: 'Zinc HTTP Server Worker'

Each #acceptWaitTimeout seconds, 'Wait for accept timed out' is printed on the 
log and another accept/wait starts. This looping improves liveliness and 
responsiveness to other events.

Sven


Reply via email to