github.com/niedbalski/juju@v0.0.0-20190215020005-8ff100488e47/worker/raft/simplefsm.go (about) 1 // Copyright 2018 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package raft 5 6 import ( 7 "encoding/gob" 8 "io" 9 "sync" 10 11 "github.com/hashicorp/raft" 12 ) 13 14 // SimpleFSM is an implementation of raft.FSM, which simply appends 15 // the log data to a slice. 16 type SimpleFSM struct { 17 mu sync.Mutex 18 logs [][]byte 19 } 20 21 // Logs returns the accumulated log data. 22 func (fsm *SimpleFSM) Logs() [][]byte { 23 fsm.mu.Lock() 24 defer fsm.mu.Unlock() 25 copied := make([][]byte, len(fsm.logs)) 26 copy(copied, fsm.logs) 27 return copied 28 } 29 30 // Apply is part of the raft.FSM interface. 31 func (fsm *SimpleFSM) Apply(log *raft.Log) interface{} { 32 fsm.mu.Lock() 33 defer fsm.mu.Unlock() 34 fsm.logs = append(fsm.logs, log.Data) 35 return len(fsm.logs) 36 } 37 38 // Snapshot is part of the raft.FSM interface. 39 func (fsm *SimpleFSM) Snapshot() (raft.FSMSnapshot, error) { 40 fsm.mu.Lock() 41 defer fsm.mu.Unlock() 42 copied := make([][]byte, len(fsm.logs)) 43 copy(copied, fsm.logs) 44 return &SimpleSnapshot{copied, len(copied)}, nil 45 } 46 47 // Restore is part of the raft.FSM interface. 48 func (fsm *SimpleFSM) Restore(rc io.ReadCloser) error { 49 defer rc.Close() 50 var logs [][]byte 51 if err := gob.NewDecoder(rc).Decode(&logs); err != nil { 52 return err 53 } 54 fsm.mu.Lock() 55 fsm.logs = logs 56 fsm.mu.Unlock() 57 return nil 58 } 59 60 // SimpleSnapshot is an implementation of raft.FSMSnapshot, returned 61 // by the SimpleFSM.Snapshot in this package. 62 type SimpleSnapshot struct { 63 logs [][]byte 64 n int 65 } 66 67 // Persist is part of the raft.FSMSnapshot interface. 68 func (snap *SimpleSnapshot) Persist(sink raft.SnapshotSink) error { 69 if err := gob.NewEncoder(sink).Encode(snap.logs[:snap.n]); err != nil { 70 sink.Cancel() 71 return err 72 } 73 sink.Close() 74 return nil 75 } 76 77 // Release is part of the raft.FSMSnapshot interface. 78 func (*SimpleSnapshot) Release() {}