func (serviceCatalog *ServiceCatalog) Add(service *service.Service) {
	nodeID := service.NodeID()
	key := createKey(service.Name(), service.Version(), nodeID)
	serviceCatalog.services.Store(key, ServiceEntry{service, nodeID})
	value, exists := serviceCatalog.servicesByName.Load(service.FullName())
	if exists {
		serviceCatalog.servicesByName.Store(service.FullName(), value.(int)+1)
		serviceCatalog.servicesByName.Store(service.Name(), value.(int)+1)
	} else {
		serviceCatalog.servicesByName.Store(service.FullName(), 1)
		serviceCatalog.servicesByName.Store(service.Name(), 1)
	}
}
Add : add a service to the catalog.
package registry
import (
	"fmt"
	"sync"
	"github.com/moleculer-go/moleculer/service"
	log "github.com/sirupsen/logrus"
)
type ServiceCatalog struct {
	services       sync.Map
	servicesByName sync.Map
	logger         *log.Entry
}
type ServiceEntry struct {
	service *service.Service
	nodeID  string
}
func CreateServiceCatalog(logger *log.Entry) *ServiceCatalog {
	services := sync.Map{}
	servicesByName := sync.Map{}
	return &ServiceCatalog{services, servicesByName, logger}
}
func createKey(name, version, nodeID string) string {
	return fmt.Sprintf("%s:%s:%s", nodeID, name, version)
}
func (serviceCatalog *ServiceCatalog) Find(name string, version string, nodeID string) bool {
	key := createKey(name, version, nodeID)
	_, exists := serviceCatalog.services.Load(key)
	return exists
}
func (serviceCatalog *ServiceCatalog) FindByName(name string) bool {
	_, exists := serviceCatalog.servicesByName.Load(name)
	return exists
}
func (serviceCatalog *ServiceCatalog) Get(name string, version string, nodeID string) *service.Service {
	key := createKey(name, version, nodeID)
	item, exists := serviceCatalog.services.Load(key)
	if exists {
		svc := item.(service.Service)
		return &svc
	}
	return nil
}
func (serviceCatalog *ServiceCatalog) listByName() map[string][]ServiceEntry {
	result := make(map[string][]ServiceEntry)
	serviceCatalog.services.Range(func(key, value interface{}) bool {
		serviceEntry := value.(ServiceEntry)
		name := serviceEntry.service.FullName()
		entries, exists := result[name]
		if exists {
			result[name] = append(entries, serviceEntry)
		} else {
			result[name] = []ServiceEntry{serviceEntry}
		}
		return true
	})
	return result
}
func (serviceCatalog *ServiceCatalog) RemoveByNode(nodeID string) []*service.Service {
	var removed []*service.Service
	serviceCatalog.logger.Debug("RemoveByNode() nodeID: ", nodeID)
	var keysRemove []string
	var namesRemove []string
	var fullNamesRemove []string
	serviceCatalog.services.Range(func(key, value interface{}) bool {
		service := value.(ServiceEntry)
		if service.nodeID == nodeID {
			service := value.(ServiceEntry)
			removed = append(removed, service.service)
			keysRemove = append(keysRemove, key.(string))
			namesRemove = append(namesRemove, service.service.Name())
			fullNamesRemove = append(fullNamesRemove, service.service.FullName())
		}
		return true
	})
	for _, key := range keysRemove {
		serviceCatalog.services.Delete(key)
	}
	for _, name := range namesRemove {
		value, exists := serviceCatalog.servicesByName.Load(name)
		if exists {
			counter := value.(int)
			counter = counter - 1
			if counter < 0 {
				counter = 0
			}
			serviceCatalog.servicesByName.Store(name, counter)
		}
	}
	for _, name := range fullNamesRemove {
		value, exists := serviceCatalog.servicesByName.Load(name)
		if exists {
			counter := value.(int)
			counter = counter - 1
			if counter < 0 {
				counter = 0
			}
			serviceCatalog.servicesByName.Store(name, counter)
		}
	}
	return removed
}