Fix: close error conn

pull/43/head
zijiren233 3 years ago
parent c796738e6f
commit 5a972e815c

@ -49,6 +49,12 @@ type Backends struct {
emby map[string]EmbyInterface emby map[string]EmbyInterface
} }
func (b *Backends) Close() {
for _, conn := range b.conns {
conn.Conn.Close()
}
}
func (b *Backends) Conns() map[string]*BackendConnInfo { func (b *Backends) Conns() map[string]*BackendConnInfo {
return b.conns return b.conns
} }
@ -65,21 +71,26 @@ func (b *Backends) EmbyClients() map[string]EmbyInterface {
return b.emby 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)) newConns := make(map[string]*BackendConnInfo, len(conf))
backends := &Backends{ backends = &Backends{
conns: newConns, conns: newConns,
bilibili: make(map[string]BilibiliInterface), bilibili: make(map[string]BilibiliInterface),
alist: make(map[string]AlistInterface), alist: make(map[string]AlistInterface),
emby: make(map[string]EmbyInterface), emby: make(map[string]EmbyInterface),
} }
for _, vb := range conf { defer func() {
cc, err := NewGrpcClientConn(ctx, &vb.Backend)
if err != nil { if err != nil {
return nil, err backends.Close()
} }
}()
for _, vb := range conf {
if _, ok := newConns[vb.Backend.Endpoint]; ok { 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{ newConns[vb.Backend.Endpoint] = &BackendConnInfo{
Conn: cc, Conn: cc,
@ -87,31 +98,31 @@ func NewBackends(ctx context.Context, conf []*model.VendorBackend) (*Backends, e
} }
if vb.UsedBy.Bilibili { if vb.UsedBy.Bilibili {
if _, ok := backends.bilibili[vb.UsedBy.BilibiliBackendName]; ok { 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) cli, err := NewBilibiliGrpcClient(cc)
if err != nil { if err != nil {
return nil, err return backends, err
} }
backends.bilibili[vb.UsedBy.BilibiliBackendName] = cli backends.bilibili[vb.UsedBy.BilibiliBackendName] = cli
} }
if vb.UsedBy.Alist { if vb.UsedBy.Alist {
if _, ok := backends.alist[vb.UsedBy.AlistBackendName]; ok { 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) cli, err := NewAlistGrpcClient(cc)
if err != nil { if err != nil {
return nil, err return backends, err
} }
backends.alist[vb.UsedBy.AlistBackendName] = cli backends.alist[vb.UsedBy.AlistBackendName] = cli
} }
if vb.UsedBy.Emby { if vb.UsedBy.Emby {
if _, ok := backends.emby[vb.UsedBy.EmbyBackendName]; ok { 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) cli, err := NewEmbyGrpcClient(cc)
if err != nil { if err != nil {
return nil, err return backends, err
} }
backends.emby[vb.UsedBy.EmbyBackendName] = cli backends.emby[vb.UsedBy.EmbyBackendName] = cli
} }

@ -3,6 +3,7 @@ package handlers
import ( import (
"net/http" "net/http"
"reflect" "reflect"
"sync"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
"github.com/synctv-org/synctv/internal/bootstrap" "github.com/synctv-org/synctv/internal/bootstrap"
@ -716,6 +717,8 @@ func AdminGetVendorBackends(ctx *gin.Context) {
ctx.JSON(http.StatusOK, model.NewApiDataResp(resp)) ctx.JSON(http.StatusOK, model.NewApiDataResp(resp))
} }
var vendorBackendLock sync.Mutex
func AdminAddVendorBackends(ctx *gin.Context) { func AdminAddVendorBackends(ctx *gin.Context) {
// user := ctx.MustGet("user").(*op.User) // user := ctx.MustGet("user").(*op.User)
@ -725,6 +728,12 @@ func AdminAddVendorBackends(ctx *gin.Context) {
return return
} }
if !vendorBackendLock.TryLock() {
ctx.AbortWithStatusJSON(http.StatusConflict, model.NewApiErrorStringResp("vendor backend is updating"))
return
}
defer vendorBackendLock.Unlock()
vb, err := db.GetAllVendorBackend() vb, err := db.GetAllVendorBackend()
if err != nil { if err != nil {
ctx.AbortWithStatusJSON(http.StatusInternalServerError, model.NewApiErrorResp(err)) ctx.AbortWithStatusJSON(http.StatusInternalServerError, model.NewApiErrorResp(err))
@ -741,6 +750,7 @@ func AdminAddVendorBackends(ctx *gin.Context) {
err = db.CreateVendorBackend((*dbModel.VendorBackend)(&req)) err = db.CreateVendorBackend((*dbModel.VendorBackend)(&req))
if err != nil { if err != nil {
backends.Close()
ctx.AbortWithStatusJSON(http.StatusBadRequest, model.NewApiErrorResp(err)) ctx.AbortWithStatusJSON(http.StatusBadRequest, model.NewApiErrorResp(err))
return return
} }
@ -759,6 +769,12 @@ func AdminDeleteVendorBackends(ctx *gin.Context) {
return return
} }
if !vendorBackendLock.TryLock() {
ctx.AbortWithStatusJSON(http.StatusConflict, model.NewApiErrorStringResp("vendor backend is updating"))
return
}
defer vendorBackendLock.Unlock()
err := db.DeleteVendorBackends(req.Endpoints) err := db.DeleteVendorBackends(req.Endpoints)
if err != nil { if err != nil {
ctx.AbortWithStatusJSON(http.StatusBadRequest, model.NewApiErrorResp(err)) ctx.AbortWithStatusJSON(http.StatusBadRequest, model.NewApiErrorResp(err))
@ -791,6 +807,12 @@ func AdminUpdateVendorBackends(ctx *gin.Context) {
return return
} }
if !vendorBackendLock.TryLock() {
ctx.AbortWithStatusJSON(http.StatusConflict, model.NewApiErrorStringResp("vendor backend is updating"))
return
}
defer vendorBackendLock.Unlock()
vb, err := db.GetAllVendorBackend() vb, err := db.GetAllVendorBackend()
if err != nil { if err != nil {
ctx.AbortWithStatusJSON(http.StatusInternalServerError, model.NewApiErrorResp(err)) ctx.AbortWithStatusJSON(http.StatusInternalServerError, model.NewApiErrorResp(err))
@ -812,6 +834,7 @@ func AdminUpdateVendorBackends(ctx *gin.Context) {
err = db.SaveVendorBackend((*dbModel.VendorBackend)(&req)) err = db.SaveVendorBackend((*dbModel.VendorBackend)(&req))
if err != nil { if err != nil {
backends.Close()
ctx.AbortWithStatusJSON(http.StatusBadRequest, model.NewApiErrorResp(err)) ctx.AbortWithStatusJSON(http.StatusBadRequest, model.NewApiErrorResp(err))
return return
} }

Loading…
Cancel
Save