ev1lQuark commented on code in PR #113:
URL: https://github.com/apache/dubbo-kubernetes/pull/113#discussion_r1437563229
##########
pkg/admin/cache/registry/universal/cache.go:
##########
@@ -0,0 +1,474 @@
+package universal
+
+import (
+ "sync"
+
+ "dubbo.apache.org/dubbo-go/v3/common"
+ "github.com/apache/dubbo-kubernetes/pkg/admin/cache"
+ "github.com/apache/dubbo-kubernetes/pkg/admin/cache/selector"
+ "github.com/apache/dubbo-kubernetes/pkg/admin/constant"
+ "github.com/apache/dubbo-kubernetes/pkg/admin/model"
+ "github.com/apache/dubbo-kubernetes/pkg/admin/util"
+)
+
+var UniversalCacheInstance *UniversalCache
+
+func NewUniversalCache() *UniversalCache {
+ return &UniversalCache{
+ providers: &cacheMap{
+ data:
make(map[string]map[string]map[string]*DubboModel),
+ },
+ consumers: &cacheMap{
+ data:
make(map[string]map[string]map[string]*DubboModel),
+ },
+ idCache: sync.Map{},
+ }
+}
+
+type UniversalCache struct {
+ providers *cacheMap
+ consumers *cacheMap
+ idCache sync.Map
+}
+
+// cacheMap is a cache container for dubbo provider or consumer, before
reading or writing its data, you need to lock it.
+type cacheMap struct {
+ data map[string]map[string]map[string]*DubboModel // application ->
serviceKey -> serviceId -> model
+ lock sync.RWMutex
+}
+
+// set is used to store a DubboModel in cacheMap
+func (cm *cacheMap) set(applicationName, serviceKey, serviceId string, model
*DubboModel) {
+ cm.lock.Lock()
+ defer cm.lock.Unlock()
+ applicationMap := cm.data
+ if _, ok := applicationMap[applicationName]; !ok {
+ applicationMap[applicationName] =
map[string]map[string]*DubboModel{}
+ }
+ serviceMap := applicationMap[applicationName]
+ if _, ok := serviceMap[serviceKey]; !ok {
+ serviceMap[serviceKey] = map[string]*DubboModel{}
+ }
+ instanceMap := serviceMap[serviceKey]
+ instanceMap[serviceId] = model
+}
+
+// get is used to get a DubboModel from cacheMap
+func (cm *cacheMap) get(applicationName, serviceKey, serviceId string) (actual
*DubboModel, ok bool) {
+ cm.lock.RLock()
+ defer cm.lock.RUnlock()
+ applicationMap := cm.data
+ if serviceMap, ok := applicationMap[applicationName]; !ok {
+ return nil, false
+ } else {
+ if instanceMap, ok := serviceMap[serviceKey]; !ok {
+ return nil, false
+ } else {
+ return instanceMap[serviceId], true
+ }
+ }
+}
+
+// delete is used to delete a DubboModel from cacheMap
+func (cm *cacheMap) delete(applicationName, serviceKey, serviceId string) {
+ cm.lock.Lock()
+ defer cm.lock.Unlock()
+ applicationMap := cm.data
+ if serviceMap, ok := applicationMap[applicationName]; ok {
+ if instanceMap, ok := serviceMap[serviceKey]; ok {
+ delete(instanceMap, serviceId)
+ }
+ }
+}
+
+// GetApplications returns all applications in the registry.
+func (uc *UniversalCache) GetApplications(namespace string)
([]*cache.ApplicationModel, error) {
+ applicationSet := map[string]struct{}{} // it's used to deduplicate
+
+ uc.providers.lock.RLock()
+ for name := range uc.providers.data {
+ applicationSet[name] = struct{}{}
+ }
+ uc.providers.lock.RUnlock()
+
+ uc.consumers.lock.RLock()
+ for name := range uc.consumers.data {
+ applicationSet[name] = struct{}{}
+ }
+ uc.consumers.lock.RUnlock()
+
+ applications := make([]*cache.ApplicationModel, 0, len(applicationSet))
+ for name := range applicationSet {
+ applications = append(applications,
&cache.ApplicationModel{Name: name})
+ }
+
+ return applications, nil
+}
+
+func (uc *UniversalCache) GetWorkloads(namespace string)
([]*cache.WorkloadModel, error) {
+ return []*cache.WorkloadModel{}, nil
+}
+
+func (uc *UniversalCache) GetWorkloadsWithSelector(namespace string, selector
selector.Selector) ([]*cache.WorkloadModel, error) {
+ return []*cache.WorkloadModel{}, nil
+}
+
+// GetInstances returns all instances in the registry.
+//
+// An instance is a URL record in the registry, and the key of instance is IP
+ Port.
+func (uc *UniversalCache) GetInstances(namespace string)
([]*cache.InstanceModel, error) {
+ res := make([]*cache.InstanceModel, 0)
+ instanceSet := map[string]struct{}{} // it's used to deduplicate
+
+ uc.providers.lock.RLock()
+ for application, serviceMap := range uc.providers.data {
+ for serviceKey, instanceMap := range serviceMap {
+ for _, dubboModel := range instanceMap {
+ if _, ok :=
instanceSet[dubboModel.Ip+":"+dubboModel.Port]; ok {
+ continue
+ } else {
+
instanceSet[dubboModel.Ip+":"+dubboModel.Port] = struct{}{}
+ res = append(res, &cache.InstanceModel{
+ Application:
&cache.ApplicationModel{Name: application},
+ Workload: nil,
+ Name: serviceKey + "#" +
dubboModel.Ip + ":" + dubboModel.Port,
+ Ip: dubboModel.Ip,
+ Port: dubboModel.Port,
+ Status: "",
+ Node: "",
+ Labels: nil,
+ })
+ }
+ }
+ }
+ }
+ uc.providers.lock.RUnlock()
+
+ uc.consumers.lock.RLock()
+ for application, serviceMap := range uc.consumers.data {
+ for serviceKey, instanceMap := range serviceMap {
+ for _, dubboModel := range instanceMap {
+ if _, ok :=
instanceSet[dubboModel.Ip+":"+dubboModel.Port]; ok {
+ continue
+ } else {
+
instanceSet[dubboModel.Ip+":"+dubboModel.Port] = struct{}{}
+ res = append(res, &cache.InstanceModel{
+ Application:
&cache.ApplicationModel{Name: application},
+ Workload: nil,
+ Name: serviceKey + "#" +
dubboModel.Ip + ":" + dubboModel.Port,
+ Ip: dubboModel.Ip,
+ Port: dubboModel.Port,
+ Status: "",
+ Node: "",
+ Labels: nil,
+ })
+ }
+ }
+ }
+ }
+ uc.consumers.lock.RUnlock()
+
+ return res, nil
+}
+
+func (uc *UniversalCache) GetInstancesWithSelector(namespace string, selector
selector.Selector) ([]*cache.InstanceModel, error) {
+ res := make([]*cache.InstanceModel, 0)
+ instanceSet := map[string]struct{}{}
+
+ uc.providers.lock.RLock()
+ for application, serviceMap := range uc.providers.data {
+ if targetApplication, ok := selector.ApplicationOption(); ok &&
targetApplication != application {
+ continue
+ } else {
+ for serviceKey, instanceMap := range serviceMap {
+ for _, dubboModel := range instanceMap {
+ if _, ok :=
instanceSet[dubboModel.Ip+":"+dubboModel.Port]; ok {
+ continue
+ } else {
+
instanceSet[dubboModel.Ip+":"+dubboModel.Port] = struct{}{}
+ res = append(res,
&cache.InstanceModel{
+ Application:
&cache.ApplicationModel{Name: application},
+ Workload: nil,
+ Name: serviceKey
+ "#" + dubboModel.Ip + ":" + dubboModel.Port,
+ Ip:
dubboModel.Ip,
+ Port:
dubboModel.Port,
+ Status: "",
+ Node: "",
+ Labels: nil,
+ })
+ }
+ }
+ }
+ }
+ }
+ uc.providers.lock.RUnlock()
+
+ uc.consumers.lock.RLock()
+ for application, serviceMap := range uc.consumers.data {
+ if targetApplication, ok := selector.ApplicationOption(); ok &&
targetApplication != application {
+ continue
+ } else {
+ for serviceKey, instanceMap := range serviceMap {
+ for _, dubboModel := range instanceMap {
+ if _, ok :=
instanceSet[dubboModel.Ip+":"+dubboModel.Port]; ok {
+ continue
+ } else {
+
instanceSet[dubboModel.Ip+":"+dubboModel.Port] = struct{}{}
+ res = append(res,
&cache.InstanceModel{
+ Application:
&cache.ApplicationModel{Name: application},
+ Workload: nil,
+ Name: serviceKey
+ "#" + dubboModel.Ip + ":" + dubboModel.Port,
+ Ip:
dubboModel.Ip,
+ Port:
dubboModel.Port,
+ Status: "",
+ Node: "",
+ Labels: nil,
+ })
+ }
+ }
+ }
+ }
+ }
+ uc.consumers.lock.RUnlock()
+
+ return res, nil
+}
+
+func (uc *UniversalCache) GetServices(namespace string)
([]*cache.ServiceModel, error) {
+ res := make([]*cache.ServiceModel, 0)
+
+ uc.providers.lock.RLock()
+ for application, serviceMap := range uc.providers.data {
+ for serviceKey := range serviceMap {
+ res = append(res, &cache.ServiceModel{
+ Application: &cache.ApplicationModel{Name:
application},
+ Category: constant.ProviderSide,
+ Name: util.GetInterface(serviceKey),
+ Labels: nil,
Review Comment:
The labels filed only represent labels under kubernetes, maybe we can add a
field to represent the URL's params like params?
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]