Hi,

On Thu, Oct 27, 2016 at 9:34 PM, Peter Mogensen <a...@one.com> wrote:
>
> Technically that depends on the Server implementation.
> But in the provided http.Server extension, the answer is "nothing":
>
> func (srv *Server) Shutdown() {
>         srv.runlock.Lock()
>         defer srv.runlock.Unlock()
>         if !srv.running {
>                 return
>         }
>         <-srv.shutdown
> }
>
>> If the
>> answer is "nothing" then there is necessarily a small window of time,
>> after calling "Serve()" when shutdown calls will be ignored.
>
> Yes... but the semantics are clear. Shutdown() is an sync signal which will
> be ignored by servers not in a running state.
>

Yes and that's *exactly* my (only) concern with the semantics you
"propose" (otherwise I agree with you):

These is no way to (positively) know when the server will enter the
"running state". Think of this sequence:

    go func () {
        err := srv.Serve() // or .Start()
        srvEnd <- err
    }

    ... a short time after ...

    srv.Stop() // Serve() has been entered, but has not yet set
               // the "running" flag to true. Stop() is dropped.
     <- srvEnd // May wait forever!

Of course the time window after calling Serve() / Start() and before
the server enters the "running state" is very short, and *practically*
an occurrence such as the above will be *very* unlike, but still, no
matter how unlike, *there is a race* and I see no way to avoid it.

> The only other well defined semantics I can see is that any Shutdown() on a
> Server will make any current and future Serve() exit.

Yes, these are the only semantics (I see) as been "race-free", and
that's why I wrote that it "has" to be so.

> But this would prevent a restart of the Server.

My point, unless you provide an additional method, like Reset().

>
> Yes... but what about multiple Shutdown() invokations?
>

No problem. Under "my" semantics, once you call Shutdown() on a server
instance it cannot run again, unless you explicitly call Reset().

>
> There is a 3rd method ... (namely Wait() ) ... but it's not used for that.
> It's used for Servers which can be restarted before they are completely
> cleaned up. ... like in the provided http.Server extension where the old
> connectionManager can keep on shutting down HTTP Keepalive connections while
> the server object is restarted.
>

Ok, such behavior is irrelevant in my case: That is, in my case, once
Serve() / Start() returns, there is nothing remaining running, related
to that server.

> The thing you get from Context is just a way to supply the channel used for
> signaling from the outside for every Serve(Context) call. So you know
> exactly which invocation of Serve() you are canceling.
>
> In that regard you are right.

Exactly.

> However... I can't really see that's the only valid semantics. Specifically
> ... if I want to tie the Shutdown() signal to an OS Signal (like SIGTERM)...
> then how do I know which Serve() invocation to cancel?

If you want to cancel all of them, then the SIGTERM handler will have
to loop over and call the "cancel"s for all contexts. No ambiguity
there.

/npat

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to