code: func shouldRetry(c context.Context, a *model.Attempt, stat dm.AbnormalFinish_Status) (retry bool, err error) {
  	if !stat.CouldRetry() {
  		return
  	}
  	q := model.QuestFromID(a.ID.Quest)
  
  	if err = ds.Get(ds.WithoutTransaction(c), q); err != nil {
  		return
  	}
  	var cur, max uint32
  	switch stat {
  	case dm.AbnormalFinish_FAILED:
  		cur, max = a.RetryState.Failed, q.Desc.Meta.Retry.Failed
  		a.RetryState.Failed++
  	case dm.AbnormalFinish_CRASHED:
  		cur, max = a.RetryState.Crashed, q.Desc.Meta.Retry.Crashed
  		a.RetryState.Crashed++
  	case dm.AbnormalFinish_EXPIRED:
  		cur, max = a.RetryState.Expired, q.Desc.Meta.Retry.Expired
  		a.RetryState.Expired++
  	case dm.AbnormalFinish_TIMED_OUT:
  		cur, max = a.RetryState.TimedOut, q.Desc.Meta.Retry.TimedOut
  		a.RetryState.TimedOut++
  	default:
  		panic(fmt.Errorf("do not know how to retry %q", stat))
  	}
  	retry = cur < max
  	return
  }
docs: // shouldRetry loads the quest for this attempt, to determine if the attempt can
  // be retried. As a side-effect, it increments the RetryState counter for the
  // indicated failure type.
  //
  // If stat is not a retryable AbnormalFinish_Status, this will panic.