|  |  |  | @ -13,12 +13,18 @@ const ( | 
		
	
		
			
				|  |  |  |  |   AbortingLock = ReqState(4) | 
		
	
		
			
				|  |  |  |  | ) | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | type ReqInfo struct { | 
		
	
		
			
				|  |  |  |  |   State ReqState `gv:"state"` | 
		
	
		
			
				|  |  |  |  |   MsgID uuid.UUID `gv:"msg_id"` | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | type LockableExt struct{ | 
		
	
		
			
				|  |  |  |  |   State ReqState `gv:"state"` | 
		
	
		
			
				|  |  |  |  |   ReqID *uuid.UUID `gv:"req_id"` | 
		
	
		
			
				|  |  |  |  |   Owner *NodeID `gv:"owner"` | 
		
	
		
			
				|  |  |  |  |   PendingOwner *NodeID `gv:"pending_owner"` | 
		
	
		
			
				|  |  |  |  |   Requirements map[NodeID]ReqState `gv:"requirements"` | 
		
	
		
			
				|  |  |  |  |   PendingID uuid.UUID `gv:"pending_id"` | 
		
	
		
			
				|  |  |  |  |   Requirements map[NodeID]ReqInfo `gv:"requirements"` | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | func (ext *LockableExt) Type() ExtType { | 
		
	
	
		
			
				
					|  |  |  | @ -26,11 +32,14 @@ func (ext *LockableExt) Type() ExtType { | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | func NewLockableExt(requirements []NodeID) *LockableExt { | 
		
	
		
			
				|  |  |  |  |   var reqs map[NodeID]ReqState = nil | 
		
	
		
			
				|  |  |  |  |   var reqs map[NodeID]ReqInfo = nil | 
		
	
		
			
				|  |  |  |  |   if requirements != nil { | 
		
	
		
			
				|  |  |  |  |     reqs = map[NodeID]ReqState{} | 
		
	
		
			
				|  |  |  |  |     reqs = map[NodeID]ReqInfo{} | 
		
	
		
			
				|  |  |  |  |     for _, id := range(requirements) { | 
		
	
		
			
				|  |  |  |  |       reqs[id] = Unlocked | 
		
	
		
			
				|  |  |  |  |       reqs[id] = ReqInfo{ | 
		
	
		
			
				|  |  |  |  |         Unlocked, | 
		
	
		
			
				|  |  |  |  |         uuid.UUID{}, | 
		
	
		
			
				|  |  |  |  |       } | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  |   } | 
		
	
		
			
				|  |  |  |  |   return &LockableExt{ | 
		
	
	
		
			
				
					|  |  |  | @ -41,19 +50,17 @@ func NewLockableExt(requirements []NodeID) *LockableExt { | 
		
	
		
			
				|  |  |  |  |   } | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | // Send the signal to unlock a node from itself
 | 
		
	
		
			
				|  |  |  |  | func UnlockLockable(ctx *Context, owner *Node, target NodeID) (uuid.UUID, error) { | 
		
	
		
			
				|  |  |  |  | func UnlockLockable(ctx *Context, node *Node) (uuid.UUID, error) { | 
		
	
		
			
				|  |  |  |  |   msgs := Messages{} | 
		
	
		
			
				|  |  |  |  |   signal := NewLockSignal("unlock") | 
		
	
		
			
				|  |  |  |  |   msgs = msgs.Add(ctx, owner.ID, owner.Key, signal, target) | 
		
	
		
			
				|  |  |  |  |   msgs = msgs.Add(ctx, node.ID, node.Key, signal, node.ID) | 
		
	
		
			
				|  |  |  |  |   return signal.ID(), ctx.Send(msgs) | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | // Send the signal to lock a node from itself
 | 
		
	
		
			
				|  |  |  |  | func LockLockable(ctx *Context, owner *Node, target NodeID) (uuid.UUID, error) { | 
		
	
		
			
				|  |  |  |  | func LockLockable(ctx *Context, node *Node) (uuid.UUID, error) { | 
		
	
		
			
				|  |  |  |  |   msgs := Messages{} | 
		
	
		
			
				|  |  |  |  |   signal := NewLockSignal("lock") | 
		
	
		
			
				|  |  |  |  |   msgs = msgs.Add(ctx, owner.ID, owner.Key, signal, target) | 
		
	
		
			
				|  |  |  |  |   msgs = msgs.Add(ctx, node.ID, node.Key, signal, node.ID) | 
		
	
		
			
				|  |  |  |  |   return signal.ID(), ctx.Send(msgs) | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
	
		
			
				
					|  |  |  | @ -66,11 +73,20 @@ func (ext *LockableExt) HandleErrorSignal(ctx *Context, node *Node, source NodeI | 
		
	
		
			
				|  |  |  |  |   case "not_unlocked": | 
		
	
		
			
				|  |  |  |  |     if ext.State == Locking { | 
		
	
		
			
				|  |  |  |  |       ext.State = AbortingLock | 
		
	
		
			
				|  |  |  |  |       ext.Requirements[source] = Unlocked | 
		
	
		
			
				|  |  |  |  |       for id, state := range(ext.Requirements) { | 
		
	
		
			
				|  |  |  |  |         if state == Locked { | 
		
	
		
			
				|  |  |  |  |           ext.Requirements[id] = Unlocking | 
		
	
		
			
				|  |  |  |  |           msgs = msgs.Add(ctx, node.ID, node.Key, NewLockSignal("unlock"), id) | 
		
	
		
			
				|  |  |  |  |       req_info := ext.Requirements[source] | 
		
	
		
			
				|  |  |  |  |       req_info.State = Unlocked | 
		
	
		
			
				|  |  |  |  |       ext.Requirements[source] = req_info | 
		
	
		
			
				|  |  |  |  |       for id, info := range(ext.Requirements) { | 
		
	
		
			
				|  |  |  |  |         if info.State == Locked { | 
		
	
		
			
				|  |  |  |  |           lock_signal := NewLockSignal("unlock") | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |           req_info := ext.Requirements[id] | 
		
	
		
			
				|  |  |  |  |           req_info.State = Unlocking | 
		
	
		
			
				|  |  |  |  |           req_info.MsgID = lock_signal.ID() | 
		
	
		
			
				|  |  |  |  |           ext.Requirements[id] = req_info | 
		
	
		
			
				|  |  |  |  |           ctx.Log.Logf("lockable", "SENT_ABORT_UNLOCK: %s to %s", lock_signal.ID(), id) | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |           msgs = msgs.Add(ctx, node.ID, node.Key, lock_signal, id) | 
		
	
		
			
				|  |  |  |  |         } | 
		
	
		
			
				|  |  |  |  |       } | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
	
		
			
				
					|  |  |  | @ -92,9 +108,12 @@ func (ext *LockableExt) HandleLinkSignal(ctx *Context, node *Node, source NodeID | 
		
	
		
			
				|  |  |  |  |         msgs = msgs.Add(ctx, node.ID, node.Key, NewErrorSignal(signal.ID(), "already_requirement"), source) | 
		
	
		
			
				|  |  |  |  |       } else { | 
		
	
		
			
				|  |  |  |  |         if ext.Requirements == nil { | 
		
	
		
			
				|  |  |  |  |           ext.Requirements = map[NodeID]ReqState{} | 
		
	
		
			
				|  |  |  |  |           ext.Requirements = map[NodeID]ReqInfo{} | 
		
	
		
			
				|  |  |  |  |         } | 
		
	
		
			
				|  |  |  |  |         ext.Requirements[signal.NodeID] = ReqInfo{ | 
		
	
		
			
				|  |  |  |  |           Unlocked, | 
		
	
		
			
				|  |  |  |  |           uuid.UUID{}, | 
		
	
		
			
				|  |  |  |  |         } | 
		
	
		
			
				|  |  |  |  |         ext.Requirements[signal.NodeID] = Unlocked | 
		
	
		
			
				|  |  |  |  |         msgs = msgs.Add(ctx, node.ID, node.Key, NewErrorSignal(signal.ID(), "req_added"), source) | 
		
	
		
			
				|  |  |  |  |       } | 
		
	
		
			
				|  |  |  |  |     case "remove": | 
		
	
	
		
			
				
					|  |  |  | @ -114,51 +133,58 @@ func (ext *LockableExt) HandleLinkSignal(ctx *Context, node *Node, source NodeID | 
		
	
		
			
				|  |  |  |  |   return msgs | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | // Handle a LockSignal and update the extensions owner/requirement states
 | 
		
	
		
			
				|  |  |  |  | func (ext *LockableExt) HandleLockSignal(ctx *Context, node *Node, source NodeID, signal *LockSignal) Messages { | 
		
	
		
			
				|  |  |  |  |   ctx.Log.Logf("lockable", "LOCK_SIGNAL: %s->%s %+v", source, node.ID, signal.State) | 
		
	
		
			
				|  |  |  |  | func (ext *LockableExt) HandleSuccessSignal(ctx *Context, node *Node, source NodeID, signal *SuccessSignal) Messages { | 
		
	
		
			
				|  |  |  |  |   ctx.Log.Logf("lockable", "SUCCESS_SIGNAL: %+v", signal) | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |   msgs := Messages{} | 
		
	
		
			
				|  |  |  |  |   switch signal.State { | 
		
	
		
			
				|  |  |  |  |   case "locked": | 
		
	
		
			
				|  |  |  |  |     state, found := ext.Requirements[source] | 
		
	
		
			
				|  |  |  |  |     if found == false && source != node.ID { | 
		
	
		
			
				|  |  |  |  |       msgs = msgs.Add(ctx, node.ID, node.Key, NewErrorSignal(signal.ID(), "got 'locked' from non-requirement"), source) | 
		
	
		
			
				|  |  |  |  |     } else if state == Locking { | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |   info, found := ext.Requirements[source] | 
		
	
		
			
				|  |  |  |  |   ctx.Log.Logf("lockable", "State: %+v", ext.State) | 
		
	
		
			
				|  |  |  |  |   if found == false { | 
		
	
		
			
				|  |  |  |  |     ctx.Log.Logf("lockable", "Got success from non-requirement %s", source) | 
		
	
		
			
				|  |  |  |  |   } else if source == node.ID { | 
		
	
		
			
				|  |  |  |  |     // Do nothing with it
 | 
		
	
		
			
				|  |  |  |  |   } else if info.MsgID != signal.ReqID { | 
		
	
		
			
				|  |  |  |  |     ctx.Log.Logf("lockable", "Got success for wrong signal for %s: %s, expecting %s", source, signal.ReqID, info.MsgID) | 
		
	
		
			
				|  |  |  |  |   } else { | 
		
	
		
			
				|  |  |  |  |     if info.State == Locking { | 
		
	
		
			
				|  |  |  |  |       if ext.State == Locking { | 
		
	
		
			
				|  |  |  |  |         ext.Requirements[source] = Locked | 
		
	
		
			
				|  |  |  |  |         info.State = Locked | 
		
	
		
			
				|  |  |  |  |         info.MsgID = uuid.UUID{} | 
		
	
		
			
				|  |  |  |  |         ext.Requirements[source] = info | 
		
	
		
			
				|  |  |  |  |         reqs := 0 | 
		
	
		
			
				|  |  |  |  |         locked := 0 | 
		
	
		
			
				|  |  |  |  |         for _, s := range(ext.Requirements) { | 
		
	
		
			
				|  |  |  |  |           reqs += 1 | 
		
	
		
			
				|  |  |  |  |           if s == Locked { | 
		
	
		
			
				|  |  |  |  |           if s.State == Locked { | 
		
	
		
			
				|  |  |  |  |             locked += 1 | 
		
	
		
			
				|  |  |  |  |           } | 
		
	
		
			
				|  |  |  |  |         } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |         if locked == reqs { | 
		
	
		
			
				|  |  |  |  |           ctx.Log.Logf("lockable", "WHOLE LOCK: %s - %s - %+v", node.ID, ext.PendingID, ext.PendingOwner) | 
		
	
		
			
				|  |  |  |  |           ext.State = Locked | 
		
	
		
			
				|  |  |  |  |           ext.Owner = ext.PendingOwner | 
		
	
		
			
				|  |  |  |  |           msgs = msgs.Add(ctx, node.ID, node.Key, NewLockSignal("locked"), *ext.Owner) | 
		
	
		
			
				|  |  |  |  |           msgs = msgs.Add(ctx, node.ID, node.Key, NewSuccessSignal(ext.PendingID), *ext.Owner) | 
		
	
		
			
				|  |  |  |  |         } else { | 
		
	
		
			
				|  |  |  |  |           ctx.Log.Logf("lockable", "PARTIAL LOCK: %s - %d/%d", node.ID, locked, reqs) | 
		
	
		
			
				|  |  |  |  |         } | 
		
	
		
			
				|  |  |  |  |       } else if ext.State == AbortingLock { | 
		
	
		
			
				|  |  |  |  |         ext.Requirements[source] = Unlocking | 
		
	
		
			
				|  |  |  |  |         msgs = msgs.Add(ctx, node.ID, node.Key, NewLockSignal("unlock"), source) | 
		
	
		
			
				|  |  |  |  |         lock_signal := NewLockSignal("unlock") | 
		
	
		
			
				|  |  |  |  |         info.State = Unlocking | 
		
	
		
			
				|  |  |  |  |         info.MsgID = lock_signal.ID() | 
		
	
		
			
				|  |  |  |  |         ext.Requirements[source] = info | 
		
	
		
			
				|  |  |  |  |         msgs = msgs.Add(ctx, node.ID, node.Key, lock_signal, source) | 
		
	
		
			
				|  |  |  |  |       } | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  |   case "unlocked": | 
		
	
		
			
				|  |  |  |  |     state, found := ext.Requirements[source] | 
		
	
		
			
				|  |  |  |  |     if found == false { | 
		
	
		
			
				|  |  |  |  |       msgs = msgs.Add(ctx, node.ID, node.Key, NewErrorSignal(signal.ID(), "not_requirement"), source) | 
		
	
		
			
				|  |  |  |  |     } else if state == Unlocking { | 
		
	
		
			
				|  |  |  |  |       ext.Requirements[source] = Unlocked | 
		
	
		
			
				|  |  |  |  |     } else if info.State == Unlocking { | 
		
	
		
			
				|  |  |  |  |       info.State = Unlocked | 
		
	
		
			
				|  |  |  |  |       info.MsgID = uuid.UUID{} | 
		
	
		
			
				|  |  |  |  |       ext.Requirements[source] = info | 
		
	
		
			
				|  |  |  |  |       reqs := 0 | 
		
	
		
			
				|  |  |  |  |       unlocked := 0 | 
		
	
		
			
				|  |  |  |  |       for _, s := range(ext.Requirements) { | 
		
	
		
			
				|  |  |  |  |         reqs += 1 | 
		
	
		
			
				|  |  |  |  |         if s == Unlocked { | 
		
	
		
			
				|  |  |  |  |         if s.State == Unlocked { | 
		
	
		
			
				|  |  |  |  |           unlocked += 1 | 
		
	
		
			
				|  |  |  |  |         } | 
		
	
		
			
				|  |  |  |  |       } | 
		
	
	
		
			
				
					|  |  |  | @ -166,10 +192,12 @@ func (ext *LockableExt) HandleLockSignal(ctx *Context, node *Node, source NodeID | 
		
	
		
			
				|  |  |  |  |       if unlocked == reqs { | 
		
	
		
			
				|  |  |  |  |         old_state := ext.State | 
		
	
		
			
				|  |  |  |  |         ext.State = Unlocked | 
		
	
		
			
				|  |  |  |  |         ctx.Log.Logf("lockable", "WHOLE UNLOCK: %s - %s - %+v", node.ID, ext.PendingID, ext.PendingOwner) | 
		
	
		
			
				|  |  |  |  |         if old_state == Unlocking { | 
		
	
		
			
				|  |  |  |  |           previous_owner := *ext.Owner | 
		
	
		
			
				|  |  |  |  |           ext.Owner = ext.PendingOwner | 
		
	
		
			
				|  |  |  |  |           ext.ReqID = nil | 
		
	
		
			
				|  |  |  |  |           msgs = msgs.Add(ctx, node.ID, node.Key, NewLockSignal("unlocked"), *ext.Owner) | 
		
	
		
			
				|  |  |  |  |           msgs = msgs.Add(ctx, node.ID, node.Key, NewSuccessSignal(ext.PendingID), previous_owner) | 
		
	
		
			
				|  |  |  |  |         } else if old_state == AbortingLock { | 
		
	
		
			
				|  |  |  |  |           msgs = msgs.Add(ctx ,node.ID, node.Key, NewErrorSignal(*ext.ReqID, "not_unlocked"), *ext.PendingOwner) | 
		
	
		
			
				|  |  |  |  |           ext.PendingOwner = ext.Owner | 
		
	
	
		
			
				
					|  |  |  | @ -178,6 +206,17 @@ func (ext *LockableExt) HandleLockSignal(ctx *Context, node *Node, source NodeID | 
		
	
		
			
				|  |  |  |  |         ctx.Log.Logf("lockable", "PARTIAL UNLOCK: %s - %d/%d", node.ID, unlocked, reqs) | 
		
	
		
			
				|  |  |  |  |       } | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  |   } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |   return msgs | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | // Handle a LockSignal and update the extensions owner/requirement states
 | 
		
	
		
			
				|  |  |  |  | func (ext *LockableExt) HandleLockSignal(ctx *Context, node *Node, source NodeID, signal *LockSignal) Messages { | 
		
	
		
			
				|  |  |  |  |   ctx.Log.Logf("lockable", "LOCK_SIGNAL: %s->%s %+v", source, node.ID, signal.State) | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |   msgs := Messages{} | 
		
	
		
			
				|  |  |  |  |   switch signal.State { | 
		
	
		
			
				|  |  |  |  |   case "lock": | 
		
	
		
			
				|  |  |  |  |     if ext.State == Unlocked { | 
		
	
		
			
				|  |  |  |  |       if len(ext.Requirements) == 0 { | 
		
	
	
		
			
				
					|  |  |  | @ -185,19 +224,22 @@ func (ext *LockableExt) HandleLockSignal(ctx *Context, node *Node, source NodeID | 
		
	
		
			
				|  |  |  |  |         new_owner := source | 
		
	
		
			
				|  |  |  |  |         ext.PendingOwner = &new_owner | 
		
	
		
			
				|  |  |  |  |         ext.Owner = &new_owner | 
		
	
		
			
				|  |  |  |  |         msgs = msgs.Add(ctx, node.ID, node.Key, NewLockSignal("locked"), new_owner) | 
		
	
		
			
				|  |  |  |  |         msgs = msgs.Add(ctx, node.ID, node.Key, NewSuccessSignal(signal.ID()), new_owner) | 
		
	
		
			
				|  |  |  |  |       } else { | 
		
	
		
			
				|  |  |  |  |         ext.State = Locking | 
		
	
		
			
				|  |  |  |  |         id := signal.ID() | 
		
	
		
			
				|  |  |  |  |         ext.ReqID = &id | 
		
	
		
			
				|  |  |  |  |         new_owner := source | 
		
	
		
			
				|  |  |  |  |         ext.PendingOwner = &new_owner | 
		
	
		
			
				|  |  |  |  |         for id, state := range(ext.Requirements) { | 
		
	
		
			
				|  |  |  |  |           if state != Unlocked { | 
		
	
		
			
				|  |  |  |  |         ext.PendingID = signal.ID() | 
		
	
		
			
				|  |  |  |  |         for id, info := range(ext.Requirements) { | 
		
	
		
			
				|  |  |  |  |           if info.State != Unlocked { | 
		
	
		
			
				|  |  |  |  |             ctx.Log.Logf("lockable", "REQ_NOT_UNLOCKED_WHEN_LOCKING") | 
		
	
		
			
				|  |  |  |  |           } | 
		
	
		
			
				|  |  |  |  |           ext.Requirements[id] = Locking | 
		
	
		
			
				|  |  |  |  |           lock_signal := NewLockSignal("lock") | 
		
	
		
			
				|  |  |  |  |           info.State = Locking | 
		
	
		
			
				|  |  |  |  |           info.MsgID = lock_signal.ID() | 
		
	
		
			
				|  |  |  |  |           ext.Requirements[id] = info | 
		
	
		
			
				|  |  |  |  |           msgs = msgs.Add(ctx, node.ID, node.Key, lock_signal, id) | 
		
	
		
			
				|  |  |  |  |         } | 
		
	
		
			
				|  |  |  |  |       } | 
		
	
	
		
			
				
					|  |  |  | @ -211,18 +253,21 @@ func (ext *LockableExt) HandleLockSignal(ctx *Context, node *Node, source NodeID | 
		
	
		
			
				|  |  |  |  |         new_owner := source | 
		
	
		
			
				|  |  |  |  |         ext.PendingOwner = nil | 
		
	
		
			
				|  |  |  |  |         ext.Owner = nil | 
		
	
		
			
				|  |  |  |  |         msgs = msgs.Add(ctx, node.ID, node.Key, NewLockSignal("unlocked"), new_owner) | 
		
	
		
			
				|  |  |  |  |         msgs = msgs.Add(ctx, node.ID, node.Key, NewSuccessSignal(signal.ID()), new_owner) | 
		
	
		
			
				|  |  |  |  |       } else if source == *ext.Owner { | 
		
	
		
			
				|  |  |  |  |         ext.State = Unlocking | 
		
	
		
			
				|  |  |  |  |         id := signal.ID() | 
		
	
		
			
				|  |  |  |  |         ext.ReqID = &id | 
		
	
		
			
				|  |  |  |  |         ext.PendingOwner = nil | 
		
	
		
			
				|  |  |  |  |         for id, state := range(ext.Requirements) { | 
		
	
		
			
				|  |  |  |  |           if state != Locked { | 
		
	
		
			
				|  |  |  |  |         ext.PendingID = signal.ID() | 
		
	
		
			
				|  |  |  |  |         for id, info := range(ext.Requirements) { | 
		
	
		
			
				|  |  |  |  |           if info.State != Locked { | 
		
	
		
			
				|  |  |  |  |             ctx.Log.Logf("lockable", "REQ_NOT_LOCKED_WHEN_UNLOCKING") | 
		
	
		
			
				|  |  |  |  |           } | 
		
	
		
			
				|  |  |  |  |           ext.Requirements[id] = Unlocking | 
		
	
		
			
				|  |  |  |  |           lock_signal := NewLockSignal("unlock") | 
		
	
		
			
				|  |  |  |  |           info.State = Unlocking | 
		
	
		
			
				|  |  |  |  |           info.MsgID = lock_signal.ID() | 
		
	
		
			
				|  |  |  |  |           ext.Requirements[id] = info | 
		
	
		
			
				|  |  |  |  |           msgs = msgs.Add(ctx, node.ID, node.Key, lock_signal, id) | 
		
	
		
			
				|  |  |  |  |         } | 
		
	
		
			
				|  |  |  |  |       } | 
		
	
	
		
			
				
					|  |  |  | @ -258,6 +303,8 @@ func (ext *LockableExt) Process(ctx *Context, node *Node, source NodeID, signal | 
		
	
		
			
				|  |  |  |  |       messages = ext.HandleLockSignal(ctx, node, source, sig) | 
		
	
		
			
				|  |  |  |  |     case *ErrorSignal: | 
		
	
		
			
				|  |  |  |  |       messages = ext.HandleErrorSignal(ctx, node, source, sig) | 
		
	
		
			
				|  |  |  |  |     case *SuccessSignal: | 
		
	
		
			
				|  |  |  |  |       messages = ext.HandleSuccessSignal(ctx, node, source, sig) | 
		
	
		
			
				|  |  |  |  |     default: | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  |   default: | 
		
	
	
		
			
				
					|  |  |  | 
 |