code: func (mtask *managedTask) startResourceTransitions(transitionFunc resourceTransitionFunc) (bool, map[string]string) {
  	anyCanTransition := false
  	transitions := make(map[string]string)
  	for _, res := range mtask.GetResources() {
  		knownStatus := res.GetKnownStatus()
  		desiredStatus := res.GetDesiredStatus()
  		if knownStatus >= desiredStatus {
  			seelog.Debugf("Managed task [%s]: resource [%s] has already transitioned to or beyond the desired status %s; current known is %s",
  				mtask.Arn, res.GetName(), res.StatusString(desiredStatus), res.StatusString(knownStatus))
  			continue
  		}
  		anyCanTransition = true
  		transition := mtask.resourceNextState(res)
  		// If the resource is already in a transition, skip
  		if transition.actionRequired && !res.SetAppliedStatus(transition.nextState) {
  			// At least one resource is able to be moved forwards, so we're not deadlocked
  			continue
  		}
  		if !transition.actionRequired {
  			// no action is required for the transition, just set the known status without
  			// calling any transition function
  			go mtask.emitResourceChange(resourceStateChange{
  				resource:  res,
  				nextState: transition.nextState,
  				err:       nil,
  			})
  			continue
  		}
  		// At least one resource is able to be move forwards, so we're not deadlocked
  		transitions[res.GetName()] = transition.status
  		go transitionFunc(res, transition.nextState)
  	}
  	return anyCanTransition, transitions
  }
docs: // startResourceTransitions steps through each resource in the task and calls
  // the passed transition function when a transition should occur