@@ -56,14 +56,18 @@ var (
5656 snapctlRemoveChangeKind = swfeats .RegisterChangeKind ("snapctl-remove" )
5757)
5858
59+ var (
60+ changeNotFoundError = "change %q not found"
61+ )
62+
5963func init () {
6064 finalTasks = make (map [string ]bool , len (snapstate .FinalTasks ))
6165 for _ , kind := range snapstate .FinalTasks {
6266 finalTasks [kind ] = true
6367 }
6468}
6569
66- const snapctlDebounceWindow = 200 * time .Millisecond
70+ const snapctlDebounceWindow = 100 * time .Millisecond
6771
6872// finalSeedTask is the last task that should run during seeding. This is used
6973// in the special handling of the "seed" change, which requires that we
@@ -521,17 +525,17 @@ func isReady(hctx *hookstate.Context, changeID string) (state.Status, error) {
521525 chg := st .Change (changeID )
522526
523527 if chg == nil {
524- return state .DefaultStatus , fmt .Errorf ("change %q not found" , changeID )
528+ return state .DefaultStatus , fmt .Errorf (changeNotFoundError , changeID )
525529 }
526530
527531 var initiatorSnapName string
528532 err := chg .Get ("initiated-by-snap" , & initiatorSnapName )
529533 if err != nil {
530- return state .DefaultStatus , fmt .Errorf ("change %q not found" , changeID )
534+ return state .DefaultStatus , fmt .Errorf (changeNotFoundError , changeID )
531535 }
532536
533537 if initiatorSnapName != callerSnapName {
534- return state .DefaultStatus , fmt .Errorf ("change %q not found" , changeID )
538+ return state .DefaultStatus , fmt .Errorf (changeNotFoundError , changeID )
535539 }
536540
537541 wait , err := rateLimit (st , changeID , snapctlDebounceWindow )
@@ -640,8 +644,9 @@ func setChangeAccessedAt(st *state.State, accessed time.Time, changeID string) {
640644 st .Cache (key , accessed .UnixNano ())
641645}
642646
643- // changeStatus checks if the change is ready, if it is, it returns the status, otherwise st.Doing.
644- func changeStatus (hctx * hookstate.Context , changeID string ) (state.Change , error ) {
647+ // getAssociatedChange returns a change associated with the snapctl context and passed change ID,
648+ // otherwise nil with error
649+ func getAssociatedChange (hctx * hookstate.Context , changeID string ) (* state.Change , error ) {
645650 callerSnapName := hctx .InstanceName ()
646651
647652 st := hctx .State ()
@@ -651,55 +656,29 @@ func changeStatus(hctx *hookstate.Context, changeID string) (state.Change, error
651656 chg := st .Change (changeID )
652657
653658 if chg == nil {
654- return state. Change {} , fmt .Errorf ("change %q not found" , changeID )
659+ return nil , fmt .Errorf (changeNotFoundError , changeID )
655660 }
656661
657662 var initiatorSnapName string
658663 err := chg .Get ("initiated-by-snap" , & initiatorSnapName )
659664 if err != nil {
660- return state. Change {} , fmt .Errorf ("could not find initiator attribute for change %q" , changeID )
665+ return nil , fmt .Errorf (changeNotFoundError , changeID )
661666 }
662667
663668 if initiatorSnapName != callerSnapName {
664- return state. Change {} , fmt .Errorf ("change %q was initiated by another snap" , changeID )
669+ return nil , fmt .Errorf (changeNotFoundError , changeID )
665670 }
666671
667- lastAccess := st .Cached (fmt .Sprintf ("snapctl-%s-last-accessed" , callerSnapName ))
668- st .Cache (fmt .Sprintf ("snapctl-%s-last-accessed" , hctx .InstanceName ()), time .Now ().UnixNano ())
669-
670- // Compute how long to wait before checking the change status.
671- var toWait time.Duration
672- if lastAccess != nil {
673- lastAccessNano , ok := lastAccess .(int64 )
674- if ! ok {
675- return state.Change {}, fmt .Errorf ("invalid last accessed time format for change %q" , changeID )
676- }
677- toWait = 200 * time .Millisecond - time .Since (time .Unix (0 , lastAccessNano ))
672+ wait , err := rateLimit (st , changeID , snapctlDebounceWindow )
673+ if err != nil {
674+ return nil , err
678675 }
679676
680677 st .Unlock ()
678+ <- timeAfter (wait )
679+ st .Lock ()
681680
682- ready := chg .Ready ()
683-
684- if toWait <= 0 {
685- select {
686- case <- ready :
687- st .Lock ()
688- return * chg , nil
689- default :
690- st .Lock ()
691- return state.Change {}, nil
692- }
693- }
694-
695- select {
696- case <- ready :
697- st .Lock ()
698- return * chg , nil
699- case <- timeAfter (toWait ):
700- st .Lock ()
701- return state.Change {}, nil
702- }
681+ return chg , nil
703682}
704683
705684// getAttribute unmarshals into result the value of the provided key from attributes map.
0 commit comments