Skip to content

Commit

Permalink
kvscheduler: keep node in the graph during recreate
Browse files Browse the repository at this point in the history
This patch fixes issues reported in ligato#1418.
During recreate (Delete+Create) the node would be completely
removed from the graph by Delete and all the associated flags
(metadata) were therefore lost.
When the subsequent Create fails, the scheduler needs to access
the flags, which in this case are undefined, causing the scheduler
to panic by dereferencing nil pointer.
This patch ensures that the node and its flags are preserved
during re-creation.

An in-progress refactor of the scheduling algorithm
will approach value recreation in a much cleaner
way...

Signed-off-by: Milan Lenco <milan.lenco@pantheon.tech>
  • Loading branch information
Milan Lenco committed Jul 29, 2019
1 parent 75214a0 commit f2c117d
Showing 1 changed file with 7 additions and 3 deletions.
10 changes: 7 additions & 3 deletions plugins/kvscheduler/txn_exec.go
Expand Up @@ -255,7 +255,9 @@ func (s *Scheduler) applyValue(args *applyValueArgs) (executed kvs.RecordedTxnOp
}

// applyDelete removes value.
func (s *Scheduler) applyDelete(node graph.NodeRW, txnOp *kvs.RecordedTxnOp, args *applyValueArgs, pending bool) (executed kvs.RecordedTxnOps, err error) {
func (s *Scheduler) applyDelete(node graph.NodeRW, txnOp *kvs.RecordedTxnOp, args *applyValueArgs,
pending bool) (executed kvs.RecordedTxnOps, err error) {

if s.logGraphWalk {
endLog := s.logNodeVisit("applyDelete", args)
defer endLog()
Expand Down Expand Up @@ -290,7 +292,9 @@ func (s *Scheduler) applyDelete(node graph.NodeRW, txnOp *kvs.RecordedTxnOp, arg
// removed by request
txnOp.NewState = kvs.ValueState_REMOVED
if args.isDerived {
args.graphW.DeleteNode(args.kv.key)
if !txnOp.IsRecreate {
args.graphW.DeleteNode(args.kv.key)
}
} else {
s.updateNodeState(node, txnOp.NewState, args)
}
Expand Down Expand Up @@ -517,7 +521,7 @@ func (s *Scheduler) applyUpdate(node graph.NodeRW, txnOp *kvs.RecordedTxnOp, arg
descriptor := s.registry.GetDescriptorForKey(args.kv.key)
handler := newDescriptorHandler(descriptor)
if !args.dryRun && args.kv.origin == kvs.FromNB {
err = handler.validate(node.GetKey(), node.GetValue())
err = handler.validate(node.GetKey(), args.kv.value)
if err != nil {
node.SetValue(args.kv.value) // save the invalid value
node.SetFlags(&UnavailValueFlag{})
Expand Down

0 comments on commit f2c117d

Please sign in to comment.