From 5a972e815cd01984aaaec24e9a2d10e2ce28fad2 Mon Sep 17 00:00:00 2001 From: zijiren233 Date: Fri, 15 Dec 2023 13:18:16 +0800 Subject: [PATCH] Fix: close error conn --- internal/vendor/vendor.go | 35 +++++++++++++++++++++++------------ server/handlers/admin.go | 23 +++++++++++++++++++++++ 2 files changed, 46 insertions(+), 12 deletions(-) diff --git a/internal/vendor/vendor.go b/internal/vendor/vendor.go index 0c2bf18..c6e69c3 100644 --- a/internal/vendor/vendor.go +++ b/internal/vendor/vendor.go @@ -49,6 +49,12 @@ type Backends struct { emby map[string]EmbyInterface } +func (b *Backends) Close() { + for _, conn := range b.conns { + conn.Conn.Close() + } +} + func (b *Backends) Conns() map[string]*BackendConnInfo { return b.conns } @@ -65,21 +71,26 @@ func (b *Backends) EmbyClients() map[string]EmbyInterface { return b.emby } -func NewBackends(ctx context.Context, conf []*model.VendorBackend) (*Backends, error) { +func NewBackends(ctx context.Context, conf []*model.VendorBackend) (backends *Backends, err error) { newConns := make(map[string]*BackendConnInfo, len(conf)) - backends := &Backends{ + backends = &Backends{ conns: newConns, bilibili: make(map[string]BilibiliInterface), alist: make(map[string]AlistInterface), emby: make(map[string]EmbyInterface), } - for _, vb := range conf { - cc, err := NewGrpcClientConn(ctx, &vb.Backend) + defer func() { if err != nil { - return nil, err + backends.Close() } + }() + for _, vb := range conf { if _, ok := newConns[vb.Backend.Endpoint]; ok { - return nil, fmt.Errorf("duplicate endpoint: %s", vb.Backend.Endpoint) + return backends, fmt.Errorf("duplicate endpoint: %s", vb.Backend.Endpoint) + } + cc, err := NewGrpcClientConn(ctx, &vb.Backend) + if err != nil { + return backends, err } newConns[vb.Backend.Endpoint] = &BackendConnInfo{ Conn: cc, @@ -87,31 +98,31 @@ func NewBackends(ctx context.Context, conf []*model.VendorBackend) (*Backends, e } if vb.UsedBy.Bilibili { if _, ok := backends.bilibili[vb.UsedBy.BilibiliBackendName]; ok { - return nil, fmt.Errorf("duplicate bilibili backend name: %s", vb.UsedBy.BilibiliBackendName) + return backends, fmt.Errorf("duplicate bilibili backend name: %s", vb.UsedBy.BilibiliBackendName) } cli, err := NewBilibiliGrpcClient(cc) if err != nil { - return nil, err + return backends, err } backends.bilibili[vb.UsedBy.BilibiliBackendName] = cli } if vb.UsedBy.Alist { if _, ok := backends.alist[vb.UsedBy.AlistBackendName]; ok { - return nil, fmt.Errorf("duplicate alist backend name: %s", vb.UsedBy.AlistBackendName) + return backends, fmt.Errorf("duplicate alist backend name: %s", vb.UsedBy.AlistBackendName) } cli, err := NewAlistGrpcClient(cc) if err != nil { - return nil, err + return backends, err } backends.alist[vb.UsedBy.AlistBackendName] = cli } if vb.UsedBy.Emby { if _, ok := backends.emby[vb.UsedBy.EmbyBackendName]; ok { - return nil, fmt.Errorf("duplicate emby backend name: %s", vb.UsedBy.EmbyBackendName) + return backends, fmt.Errorf("duplicate emby backend name: %s", vb.UsedBy.EmbyBackendName) } cli, err := NewEmbyGrpcClient(cc) if err != nil { - return nil, err + return backends, err } backends.emby[vb.UsedBy.EmbyBackendName] = cli } diff --git a/server/handlers/admin.go b/server/handlers/admin.go index 59508b6..044e98e 100644 --- a/server/handlers/admin.go +++ b/server/handlers/admin.go @@ -3,6 +3,7 @@ package handlers import ( "net/http" "reflect" + "sync" "github.com/gin-gonic/gin" "github.com/synctv-org/synctv/internal/bootstrap" @@ -716,6 +717,8 @@ func AdminGetVendorBackends(ctx *gin.Context) { ctx.JSON(http.StatusOK, model.NewApiDataResp(resp)) } +var vendorBackendLock sync.Mutex + func AdminAddVendorBackends(ctx *gin.Context) { // user := ctx.MustGet("user").(*op.User) @@ -725,6 +728,12 @@ func AdminAddVendorBackends(ctx *gin.Context) { return } + if !vendorBackendLock.TryLock() { + ctx.AbortWithStatusJSON(http.StatusConflict, model.NewApiErrorStringResp("vendor backend is updating")) + return + } + defer vendorBackendLock.Unlock() + vb, err := db.GetAllVendorBackend() if err != nil { ctx.AbortWithStatusJSON(http.StatusInternalServerError, model.NewApiErrorResp(err)) @@ -741,6 +750,7 @@ func AdminAddVendorBackends(ctx *gin.Context) { err = db.CreateVendorBackend((*dbModel.VendorBackend)(&req)) if err != nil { + backends.Close() ctx.AbortWithStatusJSON(http.StatusBadRequest, model.NewApiErrorResp(err)) return } @@ -759,6 +769,12 @@ func AdminDeleteVendorBackends(ctx *gin.Context) { return } + if !vendorBackendLock.TryLock() { + ctx.AbortWithStatusJSON(http.StatusConflict, model.NewApiErrorStringResp("vendor backend is updating")) + return + } + defer vendorBackendLock.Unlock() + err := db.DeleteVendorBackends(req.Endpoints) if err != nil { ctx.AbortWithStatusJSON(http.StatusBadRequest, model.NewApiErrorResp(err)) @@ -791,6 +807,12 @@ func AdminUpdateVendorBackends(ctx *gin.Context) { return } + if !vendorBackendLock.TryLock() { + ctx.AbortWithStatusJSON(http.StatusConflict, model.NewApiErrorStringResp("vendor backend is updating")) + return + } + defer vendorBackendLock.Unlock() + vb, err := db.GetAllVendorBackend() if err != nil { ctx.AbortWithStatusJSON(http.StatusInternalServerError, model.NewApiErrorResp(err)) @@ -812,6 +834,7 @@ func AdminUpdateVendorBackends(ctx *gin.Context) { err = db.SaveVendorBackend((*dbModel.VendorBackend)(&req)) if err != nil { + backends.Close() ctx.AbortWithStatusJSON(http.StatusBadRequest, model.NewApiErrorResp(err)) return }