Skip to content

Instantly share code, notes, and snippets.

@miguelcnf
Last active January 29, 2021 20:56
Show Gist options
  • Save miguelcnf/36f73d527eb25eb19a933e8467980a5f to your computer and use it in GitHub Desktop.
Save miguelcnf/36f73d527eb25eb19a933e8467980a5f to your computer and use it in GitHub Desktop.
Idiomatic, simple, defer-based rollback mechanism https://play.golang.org/p/p28rpnpiUcL
package main
import (
"errors"
"log"
)
// rollback function
func rollback(rollbackCtrl *bool, rollbackFunc func()) {
if *rollbackCtrl {
rollbackFunc()
}
}
// successful action
func action1() (string, error) {
return "action 1", nil
}
// successful action
func action2() (string, error) {
return "action 2", nil
}
// failed action
func action3() (string, error) {
return "", errors.New("error: action 3")
}
func main() {
rollbackCtrl := false
res1, err := action1()
// handle error idiomatically
if err != nil {
// mark rollback
rollbackCtrl = true
log.Print(err.Error())
return
}
// defer the rollback execution
defer rollback(&rollbackCtrl, func() {
log.Print("rollback: action 1")
})
log.Print(res1)
res2, err := action2()
if err != nil {
// mark rollback
rollbackCtrl = true
log.Print(err.Error())
return
}
defer rollback(&rollbackCtrl, func() {
log.Print("rollback: action 2")
})
log.Print(res2)
res3, err := action3()
if err != nil {
// mark rollback
rollbackCtrl = true
log.Print(err.Error())
return
}
defer rollback(&rollbackCtrl, func() {
log.Print("rollback: action 3")
})
log.Print(res3)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment