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

     1  package selector
     2  
     3  import (
     4  	"time"
     5  
     6  	"github.com/volts-dev/volts/registry"
     7  	"github.com/volts-dev/volts/registry/cacher"
     8  )
     9  
    10  type (
    11  	registrySelector struct {
    12  		config *Config
    13  		rc     cacher.ICacher
    14  	}
    15  )
    16  
    17  func (self *registrySelector) newCache() cacher.ICacher {
    18  	opts := []registry.Option{registry.WithConfigPrefixName(self.config.String())}
    19  	if self.config.Context != nil {
    20  		if t, ok := self.config.Context.Value("selector_ttl").(time.Duration); ok {
    21  			opts = append(opts, registry.RegisterTTL(t))
    22  		}
    23  	}
    24  	return cacher.New(self.config.Registry, opts...)
    25  }
    26  
    27  func (self *registrySelector) Init(opts ...Option) error {
    28  	for _, o := range opts {
    29  		o(self.config)
    30  	}
    31  
    32  	self.rc.Stop()
    33  	self.rc = self.newCache()
    34  
    35  	return nil
    36  }
    37  
    38  func (self *registrySelector) Config() *Config {
    39  	return self.config
    40  }
    41  
    42  func (self *registrySelector) Match(endpoint string, opts ...SelectOption) (Next, error) {
    43  	sopts := &SelectConfig{
    44  		Strategy: self.config.Strategy,
    45  	}
    46  	services, err := self.rc.Match(endpoint)
    47  	if err != nil {
    48  		if err == registry.ErrNotFound {
    49  			return nil, ErrNotFound
    50  		}
    51  		return nil, err
    52  	}
    53  	// if there's nothing left, return
    54  	if len(services) == 0 {
    55  		return nil, ErrNoneAvailable
    56  	}
    57  
    58  	return sopts.Strategy(services), nil
    59  }
    60  
    61  func (self *registrySelector) Select(service string, opts ...SelectOption) (Next, error) {
    62  	sopts := &SelectConfig{
    63  		Strategy: self.config.Strategy,
    64  	}
    65  
    66  	for _, opt := range opts {
    67  		opt(sopts)
    68  	}
    69  
    70  	// get the service
    71  	// try the cache first
    72  	// if that fails go directly to the registry
    73  	services, err := self.rc.GetService(service)
    74  	if err != nil {
    75  		if err == registry.ErrNotFound {
    76  			return nil, ErrNotFound
    77  		}
    78  		return nil, err
    79  	}
    80  
    81  	// apply the filters
    82  	for _, filter := range sopts.Filters {
    83  		services = filter(services)
    84  	}
    85  
    86  	// if there's nothing left, return
    87  	if len(services) == 0 {
    88  		return nil, ErrNoneAvailable
    89  	}
    90  
    91  	return sopts.Strategy(services), nil
    92  }
    93  
    94  func (self *registrySelector) Mark(service string, node *registry.Node, err error) {
    95  }
    96  
    97  func (self *registrySelector) Reset(service string) {
    98  }
    99  
   100  // Close stops the watcher and destroys the cache
   101  func (self *registrySelector) Close() error {
   102  	self.rc.Stop()
   103  
   104  	return nil
   105  }
   106  
   107  func (c *registrySelector) String() string {
   108  	return "registry"
   109  }