haproxy-lb/pkg/raft/kv.go
2021-04-08 00:34:54 +02:00

75 lines
1.3 KiB
Go

package raft
import (
"strings"
"sync"
"git.giftfish.de/ston1th/haproxy-lb/pkg/cluster"
"git.giftfish.de/ston1th/raftbbolt/msgpack"
"github.com/hashicorp/raft"
)
type kvm map[string][]byte
type kv struct {
mu sync.Mutex
m kvm
r *raft.Raft
}
func (kv *kv) Get(k string) ([]byte, error) {
kv.mu.Lock()
defer kv.mu.Unlock()
v, ok := kv.m[k]
if !ok {
return nil, cluster.ErrKeyNotFound
}
return v, nil
}
func (kv *kv) GetPrefix(pk string) (m map[string][]byte, err error) {
kv.mu.Lock()
defer kv.mu.Unlock()
m = make(map[string][]byte)
for k, v := range kv.m {
if strings.HasPrefix(k, pk) {
key := strings.TrimPrefix(k, pk)
m[key] = v
}
}
if len(m) == 0 {
err = cluster.ErrPrefixNotFound
}
return
}
func (kv *kv) Set(k string, v []byte) error {
if kv.r.State() != raft.Leader {
return cluster.ErrNotLeader
}
c := &raftCmd{SET, k, v}
b, err := msgpack.Marshal(c)
if err != nil {
return err
}
f := kv.r.Apply(b, raftTimeout)
return f.Error()
}
// Delete deletes the given key.
func (kv *kv) Delete(k string) error {
if kv.r.State() != raft.Leader {
return cluster.ErrNotLeader
}
c := &raftCmd{Op: DELETE, K: k}
b, err := msgpack.Marshal(c)
if err != nil {
return err
}
f := kv.r.Apply(b, raftTimeout)
return f.Error()
}