pkg/seqnum/seqnum.go (26 lines of code) (raw):

// Package seqnum provides utilities to persistently store sequence number in a // file and compare against the stored value to ensure a sequence number is // processed only once in the extension handler. package seqnum import ( "fmt" "io/ioutil" "os" "strconv" "github.com/pkg/errors" ) const ( // chmod is used to set the mode bits for new seqnum files. chmod = os.FileMode(0600) ) // Set replaces the stored sequence number in file, or creates a new file at // path if it does not exist. func Set(path string, num int) error { b := []byte(fmt.Sprintf("%v", num)) return errors.Wrap(ioutil.WriteFile(path, b, chmod), "seqnum: failed to write") } // IsSmallerThan returns true if the sequence number stored at path is smaller // than the provided num. If no number is stored, returns true and no // error. func IsSmallerThan(path string, num int) (bool, error) { b, err := ioutil.ReadFile(path) if err != nil { if os.IsNotExist(err) { return true, nil } return false, errors.Wrap(err, "seqnum: failed to read") } stored, err := strconv.Atoi(string(b)) return stored < num, errors.Wrapf(err, "seqnum: cannot parse number %q", b) }