From bf044de0bbb4f3eaf8ec943198f943fb965e5fb8 Mon Sep 17 00:00:00 2001 From: eastfisher Date: Sat, 5 Sep 2020 16:39:22 +0800 Subject: [PATCH] fix commit namespace config panic without prepare (#104) --- core/errors/errors.go | 3 +++ proxy/server/manager.go | 20 +++++++++++++++----- 2 files changed, 18 insertions(+), 5 deletions(-) diff --git a/core/errors/errors.go b/core/errors/errors.go index e0f2de57..9c0bfd61 100644 --- a/core/errors/errors.go +++ b/core/errors/errors.go @@ -93,4 +93,7 @@ var ( ErrInternalServer = errors.New("internal server error") // ErrUserIsReadOnly user is readonly ErrUserIsReadOnly = errors.New("user is readonly") + + // ErrNamespaceNotPrepared commit namespace config without prepare + ErrNamespaceNotPrepared = errors.New("namespace is not prepared") ) diff --git a/proxy/server/manager.go b/proxy/server/manager.go index de1f9cff..4abe3c77 100644 --- a/proxy/server/manager.go +++ b/proxy/server/manager.go @@ -25,6 +25,7 @@ import ( "sync" "time" + "github.com/XiaoMi/Gaea/core/errors" "github.com/XiaoMi/Gaea/log" "github.com/XiaoMi/Gaea/models" "github.com/XiaoMi/Gaea/mysql" @@ -32,6 +33,7 @@ import ( "github.com/XiaoMi/Gaea/stats" "github.com/XiaoMi/Gaea/stats/prometheus" "github.com/XiaoMi/Gaea/util" + "github.com/XiaoMi/Gaea/util/sync2" ) // LoadAndCreateManager load namespace config, and create manager @@ -126,10 +128,11 @@ func loadAllNamespace(cfg *models.Proxy) (map[string]*models.Namespace, error) { // Manager contains namespace manager and user manager type Manager struct { - switchIndex util.BoolIndex - namespaces [2]*NamespaceManager - users [2]*UserManager - statistics *StatisticManager + reloadPrepared sync2.AtomicBool + switchIndex util.BoolIndex + namespaces [2]*NamespaceManager + users [2]*UserManager + statistics *StatisticManager } // NewManager return empty Manager @@ -196,12 +199,19 @@ func (m *Manager) ReloadNamespacePrepare(namespaceConfig *models.Namespace) erro newUserManager := CloneUserManager(currentUserManager) newUserManager.RebuildNamespaceUsers(namespaceConfig) m.users[other] = newUserManager + m.reloadPrepared.Set(true) return nil } // ReloadNamespaceCommit commit config func (m *Manager) ReloadNamespaceCommit(name string) error { + if !m.reloadPrepared.CompareAndSwap(true, false) { + err := errors.ErrNamespaceNotPrepared + log.Warn("commit namespace error, namespace: %s, err: %v", err) + return err + } + current, _, index := m.switchIndex.Get() currentNamespace := m.namespaces[current].GetNamespace(name) @@ -836,6 +846,6 @@ func (s *StatisticManager) recordConnectPoolInuseCount(namespace string, slice s //record wait queue length func (s *StatisticManager) recordConnectPoolWaitCount(namespace string, slice string, addr string, count int64) { - statsKey := []string{s.clusterName, namespace, slice, addr} + statsKey := []string{s.clusterName, namespace, slice, addr} s.backendConnectPoolWaitCounts.Set(statsKey, count) }