github.com/polarismesh/polaris@v1.17.8/cache/namespace/namespace.go (about) 1 /** 2 * Tencent is pleased to support the open source community by making Polaris available. 3 * 4 * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. 5 * 6 * Licensed under the BSD 3-Clause License (the "License"); 7 * you may not use this file except in compliance with the License. 8 * You may obtain a copy of the License at 9 * 10 * https://opensource.org/licenses/BSD-3-Clause 11 * 12 * Unless required by applicable law or agreed to in writing, software distributed 13 * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 14 * CONDITIONS OF ANY KIND, either express or implied. See the License for the 15 * specific language governing permissions and limitations under the License. 16 */ 17 18 package namespace 19 20 import ( 21 "math" 22 "time" 23 24 "go.uber.org/zap" 25 "golang.org/x/sync/singleflight" 26 27 types "github.com/polarismesh/polaris/cache/api" 28 "github.com/polarismesh/polaris/common/log" 29 "github.com/polarismesh/polaris/common/model" 30 "github.com/polarismesh/polaris/common/utils" 31 "github.com/polarismesh/polaris/store" 32 ) 33 34 var ( 35 _ types.NamespaceCache = (*namespaceCache)(nil) 36 ) 37 38 type namespaceCache struct { 39 *types.BaseCache 40 storage store.Store 41 ids *utils.SyncMap[string, *model.Namespace] 42 updater *singleflight.Group 43 } 44 45 func NewNamespaceCache(storage store.Store, cacheMgr types.CacheManager) types.NamespaceCache { 46 return &namespaceCache{ 47 BaseCache: types.NewBaseCache(storage, cacheMgr), 48 storage: storage, 49 } 50 } 51 52 // Initialize 53 func (nsCache *namespaceCache) Initialize(c map[string]interface{}) error { 54 nsCache.ids = utils.NewSyncMap[string, *model.Namespace]() 55 nsCache.updater = new(singleflight.Group) 56 return nil 57 } 58 59 // Update 60 func (nsCache *namespaceCache) Update() error { 61 // 多个线程竞争,只有一个线程进行更新 62 _, err, _ := nsCache.updater.Do(nsCache.Name(), func() (interface{}, error) { 63 return nil, nsCache.DoCacheUpdate(nsCache.Name(), nsCache.realUpdate) 64 }) 65 return err 66 } 67 68 func (nsCache *namespaceCache) realUpdate() (map[string]time.Time, int64, error) { 69 var ( 70 lastTime = nsCache.LastFetchTime() 71 ret, err = nsCache.storage.GetMoreNamespaces(lastTime) 72 ) 73 if err != nil { 74 log.Error("[Cache][Namespace] get storage more", zap.Error(err)) 75 return nil, -1, err 76 } 77 lastMtimes := nsCache.setNamespaces(ret) 78 return lastMtimes, int64(len(ret)), nil 79 } 80 81 func (nsCache *namespaceCache) setNamespaces(nsSlice []*model.Namespace) map[string]time.Time { 82 83 lastMtime := nsCache.LastMtime(nsCache.Name()).Unix() 84 85 for index := range nsSlice { 86 ns := nsSlice[index] 87 if !ns.Valid { 88 nsCache.ids.Delete(ns.Name) 89 } else { 90 nsCache.ids.Store(ns.Name, ns) 91 } 92 93 lastMtime = int64(math.Max(float64(lastMtime), float64(ns.ModifyTime.Unix()))) 94 } 95 96 return map[string]time.Time{ 97 nsCache.Name(): time.Unix(lastMtime, 0), 98 } 99 } 100 101 // clear 102 func (nsCache *namespaceCache) Clear() error { 103 nsCache.BaseCache.Clear() 104 nsCache.ids = utils.NewSyncMap[string, *model.Namespace]() 105 return nil 106 } 107 108 // name 109 // 110 // @return string 111 func (nsCache *namespaceCache) Name() string { 112 return types.NamespaceName 113 } 114 115 // GetNamespace 116 // 117 // @receiver nsCache 118 // @param id 119 // @return *model.Namespace 120 func (nsCache *namespaceCache) GetNamespace(id string) *model.Namespace { 121 val, ok := nsCache.ids.Load(id) 122 123 if !ok { 124 return nil 125 } 126 127 return val 128 } 129 130 // GetNamespacesByName 131 // 132 // @receiver nsCache 133 // @param names 134 // @return []*model.Namespace 135 // @return error 136 func (nsCache *namespaceCache) GetNamespacesByName(names []string) []*model.Namespace { 137 nsArr := make([]*model.Namespace, 0, len(names)) 138 for _, name := range names { 139 if ns := nsCache.GetNamespace(name); ns != nil { 140 nsArr = append(nsArr, ns) 141 } 142 } 143 144 return nsArr 145 } 146 147 // GetNamespaceList 148 // 149 // @receiver nsCache 150 // @return []*model.Namespace 151 func (nsCache *namespaceCache) GetNamespaceList() []*model.Namespace { 152 nsArr := make([]*model.Namespace, 0, 8) 153 154 nsCache.ids.Range(func(key string, ns *model.Namespace) bool { 155 nsArr = append(nsArr, ns) 156 157 return true 158 }) 159 160 return nsArr 161 }