Shutdown gracefully shuts down the server without interrupting any active connections. Shutdown works by first closing all open listeners, and then waiting indefinitely for connections to close. If the provided context expires before the shutdown is complete, then the context's error is returned.
(ctx context.Context)
| 208 | // If the provided context expires before the shutdown is complete, |
| 209 | // then the context's error is returned. |
| 210 | func (srv *Server) Shutdown(ctx context.Context) error { |
| 211 | srv.mu.Lock() |
| 212 | lnerr := srv.closeListenersLocked() |
| 213 | srv.closeDoneChanLocked() |
| 214 | srv.mu.Unlock() |
| 215 | |
| 216 | finished := make(chan struct{}, 1) |
| 217 | go func() { |
| 218 | srv.listenerWg.Wait() |
| 219 | srv.connWg.Wait() |
| 220 | finished <- struct{}{} |
| 221 | }() |
| 222 | |
| 223 | select { |
| 224 | case <-ctx.Done(): |
| 225 | return ctx.Err() |
| 226 | case <-finished: |
| 227 | return lnerr |
| 228 | } |
| 229 | } |
| 230 | |
| 231 | // Serve accepts incoming connections on the Listener l, creating a new |
| 232 | // connection goroutine for each. The connection goroutines read requests and then |