Commit 2974da92 authored by ale's avatar ale

Make the Watcher strip the prefix on keys

And remove the unused StringSet type.
parent 8651bb17
......@@ -4,7 +4,6 @@ import (
"context"
"fmt"
"log"
"math/rand"
"sync"
"time"
......@@ -111,95 +110,9 @@ func NewNotifyWatchable(ctx context.Context, w Watchable) NotifyWatchable {
}
}
// A StringSet is a particular type of Watchable where we are only
// interested in the entry values, not their keys. Furthermore, the
// values are plain strings. This is useful, for instance, for a list
// of IP addresses.
//
// The StringSet keeps track of the keys, so if an entry changes value
// we can handle it correctly (the previous value is removed from the
// set).
//
// All methods are goroutine-safe. The nil value represents an empty
// but valid set.
//
type StringSet struct {
mx sync.Mutex
m map[string]string
l []string
}
// Reset the contents of the set. Implements the Watchable interface.
func (s *StringSet) Reset(m map[string]string) {
s.mx.Lock()
s.m = m
s.l = nil
for _, value := range m {
s.l = append(s.l, value)
}
s.mx.Unlock()
}
// Add an entry to the set. Implements the Watchable interface.
func (s *StringSet) Add(key, value string) {
s.mx.Lock()
if s.m == nil {
s.m = make(map[string]string)
}
oldValue, ok := s.m[key]
if ok {
s.deleteValue(oldValue)
}
s.m[key] = value
s.l = append(s.l, value)
}
// Delete an entry from the set. Implements the Watchable interface.
func (s *StringSet) Delete(key string) {
s.mx.Lock()
defer s.mx.Unlock()
if s.m == nil {
return
}
oldValue, ok := s.m[key]
if !ok {
return
}
s.deleteValue(oldValue)
delete(s.m, key)
}
func (s *StringSet) deleteValue(oldValue string) {
var l []string
for _, value := range s.l {
if value != oldValue {
l = append(l, value)
}
}
s.l = l
}
// RandomEntry returns a random entry from those currently active. If
// the list is empty, the empty string is returned.
func (s *StringSet) RandomEntry() string {
s.mx.Lock()
defer s.mx.Unlock()
if len(s.l) == 0 {
return ""
}
return s.l[rand.Intn(len(s.l))]
}
// Values returns all the currently known values.
func (s *StringSet) Values() []string {
s.mx.Lock()
defer s.mx.Unlock()
// Try to make a copy.
return append([]string{}, s.l...)
}
func watchOnce(ctx context.Context, cli *clientv3.Client, prefix string, target Watchable) error {
plen := len(prefix)
// First populate the target with a prefix-ranged Get and call
// Reset because we have all the authoritative data.
resp, err := cli.Get(ctx, prefix, clientv3.WithPrefix(), clientv3.WithSort(clientv3.SortByKey, clientv3.SortAscend))
......@@ -208,7 +121,8 @@ func watchOnce(ctx context.Context, cli *clientv3.Client, prefix string, target
}
m := make(map[string]string)
for _, ev := range resp.Kvs {
m[string(ev.Key)] = string(ev.Value)
key := string(ev.Key)[plen:]
m[key] = string(ev.Value)
}
target.Reset(m)
rev := resp.Header.Revision
......@@ -218,11 +132,12 @@ func watchOnce(ctx context.Context, cli *clientv3.Client, prefix string, target
for resp := range rch {
for _, ev := range resp.Events {
fmt.Printf("%s %q : %q\n", ev.Type, ev.Kv.Key, ev.Kv.Value)
key := string(ev.Kv.Key)[plen:]
switch ev.Type {
case clientv3.EventTypePut:
target.Set(string(ev.Kv.Key), string(ev.Kv.Value))
target.Set(key, string(ev.Kv.Value))
case clientv3.EventTypeDelete:
target.Delete(string(ev.Kv.Key))
target.Delete(key)
}
}
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment