code: func (task *Task) Name() string {
  	if task.NamePrefix == "" && task.DeduplicationKey == "" {
  		return ""
  	}
  
  	parts := make([]string, 0, 2)
  
  	if task.NamePrefix != "" {
  		parts = append(parts, task.NamePrefix)
  	}
  
  	// There's some weird restrictions on what characters are allowed inside task
  	// names. Lexicographically close names also cause hot spot problems in the
  	// Task Queues backend. To avoid these two issues, we always use SHA256 hashes
  	// as task names. Also each task kind owns its own namespace of deduplication
  	// keys, so add task type to the digest as well.
  	if task.DeduplicationKey != "" {
  		h := sha256.New()
  		if task.Payload == nil {
  			panic("task must have a Payload")
  		}
  		h.Write([]byte(proto.MessageName(task.Payload)))
  		h.Write([]byte{0})
  		h.Write([]byte(task.DeduplicationKey))
  		parts = append(parts, hex.EncodeToString(h.Sum(nil)))
  	}
  
  	return strings.Join(parts, "-")
  }
docs: // Name generates and returns the task's name.
  //
  // If the task is not a named task (doesn't have NamePrefix or DeduplicationKey
  // set), this will return an empty string.