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  }