Skip to content
Snippets Groups Projects

Commit-Confirm Mechanic for PND

Merged Ghost User requested to merge 99-commit-confirm-mechanic-for-ond-changes into develop
12 files
+ 476
59
Compare changes
  • Side-by-side
  • Inline
Files
12
+ 87
0
package pnd
import (
"github.com/google/uuid"
"github.com/openconfig/ygot/ygot"
log "github.com/sirupsen/logrus"
"sync"
"time"
)
func NewChange(device uuid.UUID, currentState ygot.GoStruct, change ygot.GoStruct, callback func(ygot.GoStruct, ygot.GoStruct) error) *Change {
return &Change{
cuid: uuid.New(),
duid: device,
timestamp: time.Now(),
previousState: currentState,
intendedState: change,
committed: false,
confirmed: false,
callback: callback,
}
}
// Change is an intended change to a OND. It is unique and immutable.
// It has a cuid, a timestamp, and holds both the previous and the new
// state. It keeps track if the state is committed and confirmed. A callback
// exists to acess the proper transport for the changed OND
type Change struct {
cuid uuid.UUID
duid uuid.UUID
timestamp time.Time
previousState ygot.GoStruct
intendedState ygot.GoStruct
committed bool
confirmed bool
callback func(ygot.GoStruct, ygot.GoStruct) error
lock sync.RWMutex
}
func (c *Change) ID() uuid.UUID {
return c.cuid
}
func (c *Change) Commit() {
c.committed = true
if err := c.callback(c.intendedState, c.previousState); err != nil {
log.WithFields(log.Fields{
"change uuid": c.cuid,
"device uuid": c.duid,
}).Error(err)
log.WithFields(log.Fields{
"change uuid": c.cuid,
"device uuid": c.duid,
}).Debug("change commited")
}
go func() {
time.Sleep(time.Minute * 10)
c.lock.RLock()
defer c.lock.RUnlock()
if !c.confirmed {
c.Rollback()
log.WithFields(log.Fields{
"change uuid": c.cuid,
"device uuid": c.duid,
}).Error("change timed out")
}
}()
}
func (c *Change) Rollback() {
if err := c.callback(c.previousState, c.intendedState); err != nil {
log.WithFields(log.Fields{
"change uuid": c.cuid,
"device uuid": c.duid,
}).Error(err)
}
}
func (c *Change) Confirm() {
c.lock.Lock()
defer c.lock.Unlock()
c.confirmed = true
log.WithFields(log.Fields{
"change uuid": c.cuid,
"device uuid": c.duid,
}).Info("change confirmed")
}
Loading