func Serve(node *core.IpfsNode, lis net.Listener, options ...ServeOption) error { handler, err := makeHandler(node, options...) if err != nil { return err } addr, err := manet.FromNetAddr(lis.Addr()) if err != nil { return err } // if the server exits beforehand var serverError error serverExited := make(chan struct{}) node.Children().Add(1) defer node.Children().Done() go func() { serverError = http.Serve(lis, handler) close(serverExited) }() // wait for server to exit. select { case <-serverExited: // if node being closed before server exits, close server case <-node.Closing(): log.Infof("server at %s terminating...", addr) lis.Close() outer: for { // wait until server exits select { case <-serverExited: // if the server exited as we are closing, we really dont care about errors serverError = nil break outer case <-time.After(5 * time.Second): log.Infof("waiting for server at %s to terminate...", addr) } } } log.Infof("server at %s terminated", addr) return serverError }