aboutsummaryrefslogtreecommitdiffhomepage
path: root/internal/system/op.go
diff options
context:
space:
mode:
authorOphestra <cat@gensokyo.uk>2025-02-17 19:00:43 +0900
committerOphestra <cat@gensokyo.uk>2025-02-17 19:00:43 +0900
commit90cb01b2748550228d0bc179691a19ebb996fc36 (patch)
tree06a2e17b578312c3f0734bf4c476e3c2eb5f6908 /internal/system/op.go
parentb1e1d5627e6532ec719c761846d7f38fe93fcadd (diff)
system: move out of internal
Signed-off-by: Ophestra <cat@gensokyo.uk>
Diffstat (limited to 'internal/system/op.go')
-rw-r--r--internal/system/op.go162
1 files changed, 0 insertions, 162 deletions
diff --git a/internal/system/op.go b/internal/system/op.go
deleted file mode 100644
index 0e421aec..00000000
--- a/internal/system/op.go
+++ /dev/null
@@ -1,162 +0,0 @@
-package system
-
-import (
- "context"
- "errors"
- "log"
- "sync"
-)
-
-const (
- // User type is reverted at final launcher exit.
- User = Enablement(ELen)
- // Process type is unconditionally reverted on exit.
- Process = Enablement(ELen + 1)
-)
-
-type Criteria struct {
- *Enablements
-}
-
-func (ec *Criteria) hasType(o Op) bool {
- // nil criteria: revert everything except User
- if ec.Enablements == nil {
- return o.Type() != User
- }
-
- return ec.Has(o.Type())
-}
-
-// Op is a reversible system operation.
-type Op interface {
- // Type returns Op's enablement type.
- Type() Enablement
-
- // apply the Op
- apply(sys *I) error
- // revert reverses the Op if criteria is met
- revert(sys *I, ec *Criteria) error
-
- Is(o Op) bool
- Path() string
- String() string
-}
-
-func TypeString(e Enablement) string {
- switch e {
- case User:
- return "User"
- case Process:
- return "Process"
- default:
- return e.String()
- }
-}
-
-// New initialises sys with no-op verbose functions.
-func New(uid int) (sys *I) {
- sys = new(I)
- sys.uid = uid
- sys.IsVerbose = func() bool { return false }
- sys.Verbose = func(...any) {}
- sys.Verbosef = func(string, ...any) {}
- sys.WrapErr = func(err error, _ ...any) error { return err }
- return
-}
-
-type I struct {
- uid int
- ops []Op
- ctx context.Context
-
- IsVerbose func() bool
- Verbose func(v ...any)
- Verbosef func(format string, v ...any)
- WrapErr func(err error, a ...any) error
-
- // whether sys has been reverted
- state bool
-
- lock sync.Mutex
-}
-
-func (sys *I) UID() int { return sys.uid }
-func (sys *I) println(v ...any) { sys.Verbose(v...) }
-func (sys *I) printf(format string, v ...any) { sys.Verbosef(format, v...) }
-func (sys *I) wrapErr(err error, a ...any) error { return sys.WrapErr(err, a...) }
-func (sys *I) wrapErrSuffix(err error, a ...any) error {
- if err == nil {
- return nil
- }
- return sys.wrapErr(err, append(a, err)...)
-}
-
-func (sys *I) Equal(v *I) bool {
- if v == nil || sys.uid != v.uid || len(sys.ops) != len(v.ops) {
- return false
- }
-
- for i, o := range sys.ops {
- if !o.Is(v.ops[i]) {
- return false
- }
- }
-
- return true
-}
-
-func (sys *I) Commit(ctx context.Context) error {
- sys.lock.Lock()
- defer sys.lock.Unlock()
-
- if sys.ctx != nil {
- panic("sys instance committed twice")
- }
- sys.ctx = ctx
-
- sp := New(sys.uid)
- sp.ops = make([]Op, 0, len(sys.ops)) // prevent copies during commits
- defer func() {
- // sp is set to nil when all ops are applied
- if sp != nil {
- // rollback partial commit
- sys.printf("commit faulted after %d ops, rolling back partial commit", len(sp.ops))
- if err := sp.Revert(&Criteria{nil}); err != nil {
- log.Println("errors returned reverting partial commit:", err)
- }
- }
- }()
-
- for _, o := range sys.ops {
- if err := o.apply(sys); err != nil {
- return err
- } else {
- // register partial commit
- sp.ops = append(sp.ops, o)
- }
- }
-
- // disarm partial commit rollback
- sp = nil
- return nil
-}
-
-func (sys *I) Revert(ec *Criteria) error {
- sys.lock.Lock()
- defer sys.lock.Unlock()
-
- if sys.state {
- panic("sys instance reverted twice")
- }
- sys.state = true
-
- // collect errors
- errs := make([]error, len(sys.ops))
-
- for i := range sys.ops {
- errs[i] = sys.ops[len(sys.ops)-i-1].revert(sys, ec)
- }
-
- // errors.Join filters nils
- return errors.Join(errs...)
-}