@@ -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
@@ -645,17 +649,17 @@ func isReady(hctx *hookstate.Context, changeID string) (state.Status, error) {
645649 chg := st .Change (changeID )
646650
647651 if chg == nil {
648- return state .DefaultStatus , fmt .Errorf ("change %q not found" , changeID )
652+ return state .DefaultStatus , fmt .Errorf (changeNotFoundError , changeID )
649653 }
650654
651655 var initiatorSnapName string
652656 err := chg .Get ("initiated-by-snap" , & initiatorSnapName )
653657 if err != nil {
654- return state .DefaultStatus , fmt .Errorf ("change %q not found" , changeID )
658+ return state .DefaultStatus , fmt .Errorf (changeNotFoundError , changeID )
655659 }
656660
657661 if initiatorSnapName != callerSnapName {
658- return state .DefaultStatus , fmt .Errorf ("change %q not found" , changeID )
662+ return state .DefaultStatus , fmt .Errorf (changeNotFoundError , changeID )
659663 }
660664
661665 wait , err := rateLimit (st , changeID , snapctlDebounceWindow )
@@ -764,8 +768,9 @@ func setChangeAccessedAt(st *state.State, accessed time.Time, changeID string) {
764768 st .Cache (key , accessed .UnixNano ())
765769}
766770
767- // changeStatus checks if the change is ready, if it is, it returns the status, otherwise st.Doing.
768- func changeStatus (hctx * hookstate.Context , changeID string ) (state.Change , error ) {
771+ // getAssociatedChange returns a change associated with the snapctl context and passed change ID,
772+ // otherwise nil with error
773+ func getAssociatedChange (hctx * hookstate.Context , changeID string ) (* state.Change , error ) {
769774 callerSnapName := hctx .InstanceName ()
770775
771776 st := hctx .State ()
@@ -775,55 +780,29 @@ func changeStatus(hctx *hookstate.Context, changeID string) (state.Change, error
775780 chg := st .Change (changeID )
776781
777782 if chg == nil {
778- return state. Change {} , fmt .Errorf ("change %q not found" , changeID )
783+ return nil , fmt .Errorf (changeNotFoundError , changeID )
779784 }
780785
781786 var initiatorSnapName string
782787 err := chg .Get ("initiated-by-snap" , & initiatorSnapName )
783788 if err != nil {
784- return state. Change {} , fmt .Errorf ("could not find initiator attribute for change %q" , changeID )
789+ return nil , fmt .Errorf (changeNotFoundError , changeID )
785790 }
786791
787792 if initiatorSnapName != callerSnapName {
788- return state. Change {} , fmt .Errorf ("change %q was initiated by another snap" , changeID )
793+ return nil , fmt .Errorf (changeNotFoundError , changeID )
789794 }
790795
791- lastAccess := st .Cached (fmt .Sprintf ("snapctl-%s-last-accessed" , callerSnapName ))
792- st .Cache (fmt .Sprintf ("snapctl-%s-last-accessed" , hctx .InstanceName ()), time .Now ().UnixNano ())
793-
794- // Compute how long to wait before checking the change status.
795- var toWait time.Duration
796- if lastAccess != nil {
797- lastAccessNano , ok := lastAccess .(int64 )
798- if ! ok {
799- return state.Change {}, fmt .Errorf ("invalid last accessed time format for change %q" , changeID )
800- }
801- toWait = 200 * time .Millisecond - time .Since (time .Unix (0 , lastAccessNano ))
796+ wait , err := rateLimit (st , changeID , snapctlDebounceWindow )
797+ if err != nil {
798+ return nil , err
802799 }
803800
804801 st .Unlock ()
802+ <- timeAfter (wait )
803+ st .Lock ()
805804
806- ready := chg .Ready ()
807-
808- if toWait <= 0 {
809- select {
810- case <- ready :
811- st .Lock ()
812- return * chg , nil
813- default :
814- st .Lock ()
815- return state.Change {}, nil
816- }
817- }
818-
819- select {
820- case <- ready :
821- st .Lock ()
822- return * chg , nil
823- case <- timeAfter (toWait ):
824- st .Lock ()
825- return state.Change {}, nil
826- }
805+ return chg , nil
827806}
828807
829808// getAttribute unmarshals into result the value of the provided key from attributes map.
0 commit comments