github.com/volts-dev/volts@v0.0.0-20240120094013-5e9c65924106/registry/registry.go (about)

     1  package registry
     2  
     3  import (
     4  	"errors"
     5  	"fmt"
     6  	"sync"
     7  
     8  	"github.com/volts-dev/volts/logger"
     9  )
    10  
    11  var (
    12  	log               = logger.New("Registry")
    13  	defaultRegistry   IRegistry
    14  	ErrNotFound       = errors.New("service not found") // Not found error when GetService is called
    15  	ErrWatcherStopped = errors.New("watcher stopped")   // Watcher stopped error when watcher is stopped
    16  	registryMap       = make(map[string]func(opts ...Option) IRegistry)
    17  	registryHost      sync.Map
    18  )
    19  
    20  type (
    21  	// 注册中心接口
    22  	IRegistry interface {
    23  		Init(...Option) error
    24  		Config() *Config
    25  		Register(*Service, ...Option) error   // 注册
    26  		Deregister(*Service, ...Option) error // 注销
    27  		GetService(string) ([]*Service, error)
    28  		ListServices() ([]*Service, error)
    29  		Watcher(...WatchOptions) (Watcher, error)
    30  		LocalServices() []*Service
    31  		String() string
    32  	}
    33  
    34  	// 微服务
    35  	Service struct {
    36  		Name      string            `json:"name"`
    37  		Version   string            `json:"version"`
    38  		Metadata  map[string]string `json:"metadata"`
    39  		Endpoints []*Endpoint       `json:"endpoints"`
    40  		Nodes     []*Node           `json:"nodes"`
    41  	}
    42  
    43  	// 微服务节点 相当于每个程序/Port一个节点
    44  	Node struct {
    45  		Id       string            `json:"id"`
    46  		Address  string            `json:"address"`
    47  		Metadata map[string]string `json:"metadata"`
    48  	}
    49  
    50  	Endpoint struct {
    51  		// RPC Method e.g. Greeter.Hello
    52  		Name string `json:"name"`
    53  		// HTTP Host e.g example.com
    54  		Host []string `json:"host"`
    55  		// HTTP Methods e.g GET, POST
    56  		Method []string `json:"method"`
    57  		// HTTP Path e.g /greeter. Expect POSIX regex
    58  		Path string `json:"path"`
    59  		// Description e.g what's this endpoint for
    60  		Description string `json:"description"`
    61  		// Stream flag
    62  		Stream bool `json:"stream"`
    63  
    64  		// 以下待确认
    65  		Request  *Value            `json:"request"`
    66  		Response *Value            `json:"response"`
    67  		Metadata map[string]string `json:"metadata"`
    68  
    69  		// API Handler e.g rpc, proxy
    70  		Handler string
    71  		// Body destination
    72  		// "*" or "" - top level message value
    73  		// "string" - inner message value
    74  		Body string
    75  	}
    76  
    77  	Value struct {
    78  		Name   string   `json:"name"`
    79  		Type   string   `json:"type"`
    80  		Values []*Value `json:"values"`
    81  	}
    82  )
    83  
    84  func Register(name string, creator func(opts ...Option) IRegistry) {
    85  	registryMap[name] = creator
    86  }
    87  
    88  func Use(name string, opts ...Option) IRegistry {
    89  	cfg := &Config{Name: name}
    90  	cfg.Init(opts...)
    91  
    92  	// 加载存在的服务
    93  	for _, addr := range cfg.Addrs {
    94  		if addr == "" {
    95  			continue
    96  		}
    97  
    98  		regName := fmt.Sprintf("%s-%s", cfg.Name, addr)
    99  		if reg, has := registryHost.Load(regName); has {
   100  			return reg.(IRegistry)
   101  		}
   102  	}
   103  
   104  	if fn, has := registryMap[name]; has {
   105  		reg := fn(opts...)
   106  		for _, addr := range reg.Config().Addrs {
   107  			if addr == "" {
   108  				continue
   109  			}
   110  
   111  			regName := fmt.Sprintf("%s-%s", cfg.Name, addr)
   112  			registryHost.Store(regName, reg)
   113  		}
   114  		return reg
   115  	}
   116  
   117  	return newNopRegistry()
   118  }
   119  
   120  // NopRegistry as default registry
   121  func Default(new ...IRegistry) IRegistry {
   122  	if new != nil {
   123  		defaultRegistry = new[0]
   124  	} else if defaultRegistry == nil {
   125  		defaultRegistry = newNopRegistry()
   126  	}
   127  
   128  	return defaultRegistry
   129  }
   130  
   131  // 比对服务节点UID是否一致,
   132  func (self *Service) Equal(to *Service) bool {
   133  	// noop 会返回nil 这里需要判断
   134  	if self != nil && len(self.Nodes) == len(to.Nodes) {
   135  		var macth bool
   136  		for _, node := range self.Nodes {
   137  			macth = false
   138  			for _, n := range to.Nodes {
   139  				if node.Id == n.Id {
   140  					macth = true
   141  					break
   142  				}
   143  			}
   144  
   145  			if !macth {
   146  				return false
   147  			}
   148  		}
   149  	}
   150  
   151  	return true
   152  }