Skip to content
Snippets Groups Projects

Develop

Closed Ghost User requested to merge develop into master
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