[ Web Proxy ]
URL:
Viewing: https://raw.githubusercontent.com/Siddhant-K-code/sourcegraph/main/internal/httpserver/server.go [Back]  [Original]

package httpserver

import (
	"context"
	"net"
	"net/http"
	"os"
	"sync"
	"time"

	"github.com/inconshreveable/log15"

	"github.com/sourcegraph/sourcegraph/internal/goroutine"
)

type server struct {
	server           *http.Server
	makeListener     func() (net.Listener, error)
	once             sync.Once
	preShutdownPause time.Duration
}

type ServerOptions func(s *server)

func WithPreShutdownPause(d time.Duration) ServerOptions {
	return func(s *server) { s.preShutdownPause = d }
}

// New returns a BackgroundRoutine that serves the given server on the given listener.
func New(listener net.Listener, httpServer *http.Server, options ...ServerOptions) goroutine.BackgroundRoutine {
	makeListener := func() (net.Listener, error) { return listener, nil }
	return newServer(httpServer, makeListener, options...)
}

// NewFromAddr returns a BackgroundRoutine that serves the given handler on the given address.
func NewFromAddr(addr string, httpServer *http.Server, options ...ServerOptions) goroutine.BackgroundRoutine {
	makeListener := func() (net.Listener, error) { return NewListener(addr) }
	return newServer(httpServer, makeListener, options...)
}

func newServer(httpServer *http.Server, makeListener func() (net.Listener, error), options ...ServerOptions) goroutine.BackgroundRoutine {
	s := &server{
		server:       httpServer,
		makeListener: makeListener,
	}

	for _, option := range options {
		option(s)
	}

	return s
}

func (s *server) Start() {
	listener, err := s.makeListener()
	if err != nil {
		log15.Error("Failed to create listener", "error", err)
		os.Exit(1)
	}

	if err := s.server.Serve(listener); err != http.ErrServerClosed {
		log15.Error("Failed to start server", "error", err)
		os.Exit(1)
	}
}

func (s *server) Stop() {
	s.once.Do(func() {
		if s.preShutdownPause > 0 {
			time.Sleep(s.preShutdownPause)
		}

		ctx, cancel := context.WithTimeout(context.Background(), goroutine.GracefulShutdownTimeout)
		defer cancel()

		if err := s.server.Shutdown(ctx); err != nil {
			log15.Error("Failed to shutdown server", "error", err)
		}
	})
}

Web Proxy Viewer  |  New URL  |  Original Page