gitee.com/h79/goutils@v1.22.10/discovery/consul/watcher.go (about)

     1  package consul
     2  
     3  import (
     4  	"context"
     5  	"gitee.com/h79/goutils/common/system"
     6  	"gitee.com/h79/goutils/discovery/service"
     7  	discoveryWatch "gitee.com/h79/goutils/discovery/watch"
     8  	consul2 "github.com/hashicorp/consul/api"
     9  	"github.com/hashicorp/consul/api/watch"
    10  )
    11  
    12  type Watcher struct {
    13  	client *consul2.Client
    14  	wc     discoveryWatch.Chan
    15  	wp     *watch.Plan
    16  	ctx    context.Context
    17  	cancel context.CancelFunc
    18  }
    19  
    20  func NewWatcher(client *consul2.Client, sizeChan int) (*Watcher, error) {
    21  	ctx, cancel := context.WithCancel(context.Background())
    22  	watcher := &Watcher{
    23  		client: client,
    24  		wc:     make(discoveryWatch.Chan, sizeChan),
    25  		wp:     nil,
    26  		ctx:    ctx,
    27  		cancel: cancel,
    28  	}
    29  	return watcher, nil
    30  }
    31  
    32  func (watcher *Watcher) Watch(key discoveryWatch.Key) (discoveryWatch.Chan, error) {
    33  	wp, err := watch.Parse(key.ToMap())
    34  	if err != nil {
    35  		return nil, err
    36  	}
    37  	watcher.wp = wp
    38  	wp.Handler = func(idx uint64, data interface{}) {
    39  		if data == nil {
    40  			return
    41  		}
    42  		sulkv, ok := data.(consul2.KVPairs)
    43  		if !ok {
    44  			return
    45  		}
    46  		for _, pairs := range sulkv {
    47  			da := service.Data{Key: service.NewKey(pairs.Key), Value: string(pairs.Value)}
    48  			watcher.wc <- discoveryWatch.Changed{
    49  				D:   da,
    50  				Cmd: discoveryWatch.Put,
    51  			}
    52  		}
    53  	}
    54  	//is a blocking
    55  	system.ChildRunning(func() {
    56  		_ = wp.RunWithClientAndHclog(watcher.client, nil)
    57  	})
    58  	return watcher.wc, nil
    59  }
    60  
    61  func (watcher *Watcher) Changed(cmd discoveryWatch.Changed) {
    62  	watcher.wc <- cmd
    63  }
    64  
    65  func (watcher *Watcher) Stop() error {
    66  	if watcher.wp != nil {
    67  		watcher.wp.Stop()
    68  		watcher.wp = nil
    69  	}
    70  	watcher.cancel()
    71  	return nil
    72  }