github.com/annwntech/go-micro/v2@v2.9.5/client/selector/default.go (about)

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