func Serve(node *core.IpfsNode, lis net.Listener, options ...ServeOption) error { handler, err := makeHandler(node, lis, 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.Process().Go(func(p goprocess.Process) { 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.Process().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 }