initial commit
This commit is contained in:
commit
7715fcf373
37 changed files with 2957 additions and 0 deletions
99
pkg/raft/fsm.go
Normal file
99
pkg/raft/fsm.go
Normal file
|
|
@ -0,0 +1,99 @@
|
|||
package raft
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"time"
|
||||
|
||||
"git.giftfish.de/ston1th/raftbbolt/msgpack"
|
||||
"github.com/hashicorp/raft"
|
||||
)
|
||||
|
||||
const (
|
||||
retainSnapshotCount = 2
|
||||
raftTimeout = 10 * time.Second
|
||||
)
|
||||
|
||||
type Op uint8
|
||||
|
||||
const (
|
||||
SET Op = iota
|
||||
DELETE
|
||||
)
|
||||
|
||||
type raftCmd struct {
|
||||
Op Op
|
||||
K string
|
||||
V []byte
|
||||
}
|
||||
|
||||
type fsm kv
|
||||
|
||||
func (f *fsm) Apply(l *raft.Log) interface{} {
|
||||
var c raftCmd
|
||||
if err := msgpack.Unmarshal(l.Data, &c); err != nil {
|
||||
panic(fmt.Sprintf("failed to unmarshal command: %s", err.Error()))
|
||||
}
|
||||
|
||||
switch c.Op {
|
||||
case SET:
|
||||
f.applySet(c.K, c.V)
|
||||
case DELETE:
|
||||
f.applyDelete(c.K)
|
||||
default:
|
||||
panic(fmt.Sprintf("unrecognized command op: %d", c.Op))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (f *fsm) Snapshot() (raft.FSMSnapshot, error) {
|
||||
f.mu.Lock()
|
||||
defer f.mu.Unlock()
|
||||
m := make(kvm)
|
||||
for k, v := range f.m {
|
||||
m[k] = v
|
||||
}
|
||||
return &fsmSnapshot{m: m}, nil
|
||||
}
|
||||
|
||||
func (f *fsm) Restore(rc io.ReadCloser) error {
|
||||
o := make(kvm)
|
||||
if err := msgpack.NewDecoder(rc).Decode(&o); err != nil {
|
||||
return err
|
||||
}
|
||||
f.m = o
|
||||
return nil
|
||||
}
|
||||
|
||||
func (f *fsm) applySet(k string, v []byte) {
|
||||
f.mu.Lock()
|
||||
f.m[k] = v
|
||||
f.mu.Unlock()
|
||||
}
|
||||
|
||||
func (f *fsm) applyDelete(k string) {
|
||||
f.mu.Lock()
|
||||
delete(f.m, k)
|
||||
f.mu.Unlock()
|
||||
}
|
||||
|
||||
type fsmSnapshot struct {
|
||||
m kvm
|
||||
}
|
||||
|
||||
func (f *fsmSnapshot) Persist(sink raft.SnapshotSink) error {
|
||||
err := func() error {
|
||||
err := msgpack.NewEncoder(sink).Encode(f.m)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return sink.Close()
|
||||
}()
|
||||
|
||||
if err != nil {
|
||||
sink.Cancel()
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func (f *fsmSnapshot) Release() {}
|
||||
Loading…
Add table
Add a link
Reference in a new issue