code: func makeProcessShardTask(job JobID, shardID, taskNum int64, named bool) *tq.Task {
  	// Note: strictly speaking including job ID in the task name is redundant,
  	// since shardID is already globally unique, but it doesn't hurt. Useful for
  	// debugging and when looking at logs and pending TQ tasks.
  	t := &tq.Task{
  		Title: fmt.Sprintf("map:job-%d-shard-%d-task-%d", job, shardID, taskNum),
  		Payload: &tasks.ProcessShard{
  			JobId:   int64(job),
  			ShardId: shardID,
  			TaskNum: taskNum,
  		},
  	}
  	if named {
  		t.DeduplicationKey = fmt.Sprintf("v1-%d-%d-%d", job, shardID, taskNum)
  	}
  	return t
  }
docs: // makeProcessShardTask creates a ProcessShard tq.Task.
  //
  // If 'named' is true, assigns it a name. Tasks are named based on their shard
  // IDs and an index in the chain of ProcessShard tasks (task number), so that
  // on retries we don't rekick already finished tasks.