Skip to content

Commit

Permalink
server: graceful shutdown notice in HTTP (#246)
Browse files Browse the repository at this point in the history
  • Loading branch information
xhebox authored Mar 10, 2023
1 parent 15a1f4f commit c369737
Show file tree
Hide file tree
Showing 6 changed files with 29 additions and 11 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -62,5 +62,5 @@ jobs:
with:
ref: ${{ inputs.ref || github.ref }}
debug: false
target: "lint test"
target: "cache"
all_platform: true
4 changes: 4 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,10 @@ tidy:
go mod tidy
cd lib && go mod tidy

cache:
go build ./...
cd lib && go build ./...

test: gocovmerge
rm -f .cover.*
go test -coverprofile=.cover.pkg ./...
Expand Down
14 changes: 10 additions & 4 deletions pkg/proxy/proxy.go
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,12 @@ func (s *SQLServer) onConn(ctx context.Context, conn net.Conn) {
clientConn.Run(ctx)
}

func (s *SQLServer) IsClosing() bool {
s.mu.RLock()
defer s.mu.RUnlock()
return s.mu.inShutdown
}

// Graceful shutdown doesn't close the listener but rejects new connections.
// Whether this affects NLB is to be tested.
func (s *SQLServer) gracefulShutdown() {
Expand All @@ -213,9 +219,9 @@ func (s *SQLServer) gracefulShutdown() {
case <-timer.C:
return
case <-time.After(100 * time.Millisecond):
s.mu.Lock()
s.mu.RLock()
allClosed := len(s.mu.clients) == 0
s.mu.Unlock()
s.mu.RUnlock()
if allClosed {
return
}
Expand All @@ -236,13 +242,13 @@ func (s *SQLServer) Close() error {
errs = append(errs, s.listener.Close())
}

s.mu.Lock()
s.mu.RLock()
for _, conn := range s.mu.clients {
if err := conn.Close(); err != nil {
errs = append(errs, err)
}
}
s.mu.Unlock()
s.mu.RUnlock()

s.wg.Wait()
return errors.Collect(ErrCloseServer, errs...)
Expand Down
6 changes: 5 additions & 1 deletion pkg/server/api/debug.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,11 @@ import (
)

func (h *HTTPServer) DebugHealth(c *gin.Context) {
c.JSON(http.StatusOK, config.HealthInfo{
status := http.StatusOK
if h.proxy.IsClosing() {
status = http.StatusBadGateway
}
c.JSON(status, config.HealthInfo{
ConfigChecksum: h.mgr.cfg.GetConfigChecksum(),
})
}
Expand Down
4 changes: 4 additions & 0 deletions pkg/server/api/http.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import (
mgrcrt "github.com/pingcap/TiProxy/pkg/manager/cert"
mgrcfg "github.com/pingcap/TiProxy/pkg/manager/config"
mgrns "github.com/pingcap/TiProxy/pkg/manager/namespace"
"github.com/pingcap/TiProxy/pkg/proxy"
"go.uber.org/atomic"
"go.uber.org/ratelimit"
"go.uber.org/zap"
Expand Down Expand Up @@ -57,17 +58,20 @@ type HTTPServer struct {
limit ratelimit.Limiter
ready *atomic.Bool
lg *zap.Logger
proxy *proxy.SQLServer
mgr managers
}

func NewHTTPServer(cfg config.API, lg *zap.Logger,
proxy *proxy.SQLServer,
nsmgr *mgrns.NamespaceManager, cfgmgr *mgrcfg.ConfigManager,
crtmgr *mgrcrt.CertManager, handler HTTPHandler,
ready *atomic.Bool) (*HTTPServer, error) {
h := &HTTPServer{
limit: ratelimit.New(DefAPILimit),
ready: ready,
lg: lg,
proxy: proxy,
mgr: managers{cfgmgr, nsmgr, crtmgr},
}

Expand Down
10 changes: 5 additions & 5 deletions pkg/server/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -87,11 +87,6 @@ func NewServer(ctx context.Context, sctx *sctx.Context) (srv *Server, err error)
return
}

// setup http
if srv.HTTPServer, err = api.NewHTTPServer(cfg.API, lg.Named("api"), srv.NamespaceManager, srv.ConfigManager, srv.CertManager, handler, ready); err != nil {
return
}

// general cluster HTTP client
{
srv.Http = &http.Client{
Expand Down Expand Up @@ -154,6 +149,11 @@ func NewServer(ctx context.Context, sctx *sctx.Context) (srv *Server, err error)
srv.Proxy.Run(ctx, srv.ConfigManager.WatchConfig())
}

// setup http
if srv.HTTPServer, err = api.NewHTTPServer(cfg.API, lg.Named("api"), srv.Proxy, srv.NamespaceManager, srv.ConfigManager, srv.CertManager, handler, ready); err != nil {
return
}

ready.Toggle()
return
}
Expand Down

0 comments on commit c369737

Please sign in to comment.