On 2016-10-27 21:34, Nick Patavalis wrote:
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!
The problem you seem to be trying to solve here is for the caller of
Shutdown() to know when the Server has exited Serve().
The way to do that under "my" semantics to implement a Server letting
you wait for it to be ready to acknowlede Shutdown()
A Serve() implementation could be done in many ways (it doesn't have to
drop Shutdown() ) ... to to extend the example it could easily once in
running state send an event on a channel you could wait on (or use a
CondVar)
So ...
func (s *Server) Serve() {
runmu.Lock()
s.running = true
runmu.Unlock()
s.IsRunningChan <- true
....
}
go func () {
err := srv.Serve()
srvEnd <- err
}
... a short time after ...
<- srv.IsRunningChan
srv.Stop()
<- srvEnd
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().
Oh... I thought you argued against the 3rd method.
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.
But how do you determine what is "all" contexts without a race condition?
You'll have to register every Serve() invocation with its context
somewhere protected by a global mutex. ... and de-register on Exit
(since you cannot call CancelFunc() twice ... (closing a closed channel
will panic).
You semantics has it's use cases... if you want to know exactly which
Serve() invocation you cancel ... but it seems to me that it complicates
the os.Signal use case ... which has almost the async semantics I use.
/Peter
--
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.