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() {}