4 ms·
> 100% agreed with the concept, but even the final example is flawed. That'll unblock and continue immediately after `close(stop)`, without being able to do two
by coder543 8y ago
> 100% agreed with the concept, but even the final example is flawed. That'll unblock and continue immediately after `close(stop)`, without being able to do two important things: it can't tell you when it's done shutting down, and it can't tell you if it encountered an error. Fixing this makes it even more complex.
The final example actually does both of these things already, but maybe you're confusing the purposes of some of the channels?
The loop at the end of main will wait until it receives one (possibly nil) error value from every task that was launched. Upon receiving the first error, it will close the done channel, which will then cause any remaining tasks to run their Shutdown function, which will attempt to gracefully shutdown the server. The error of each shutdown function is then returned and printed if non-nil.
There is no immediate termination, and all errors are communicated. It doesn't let the process die until every task has sent its error value.
Obviously, there are two semantics not enforced at compile time: each task must send exactly one error value, and each task is responsible for its own shutdown. If a task sends more than one error, there will be early termination. If a task doesn't shut itself down properly, that is its own fault.
- Groxx 8y agoShutdown blocks until draining is complete, but ListenAndServe returns immediately when Shutdown is called: https://golang.org/pkg/net/http/#Server.Shutdown https://golang.org/pkg/net/http/#Server.Shutdown >When Shutdown is called, Serve, ListenAndServe, and ListenAndServeTLS immediately return ErrServerClosed. Make sure the program doesn't exit and waits instead for Shutdown to return. So no, this writes to the "done" channel essentially immediately once `close(stop)` is called, and ends the process prematurely.