package main

import (
	"context"
	"fmt"
	"time"
)

func subTask(ctx context.Context, name string, d time.Duration) {
	select {
	case <-ctx.Done():
		fmt.Println(name, "提前被取消:", ctx.Err())
	case <-time.After(d):
		fmt.Println(name, "完成，用时", d)
	}
}

func mainTask(ctx context.Context) {
	// 从上游 ctx 派生两个子 context
	ctx1, cancel1 := context.WithCancel(ctx)
	defer cancel1()

	ctx2, cancel2 := context.WithTimeout(ctx, 2*time.Second)
	defer cancel2()

	go subTask(ctx1, "subTask-1", 5*time.Second)
	go subTask(ctx2, "subTask-2", 5*time.Second)

	time.Sleep(1 * time.Second)
	fmt.Println("mainTask: 主动取消 subTask-1 的 ctx1")
	cancel1()

	// 等待一会儿，看 subTask-2 是否因超时被取消
	time.Sleep(3 * time.Second)
}

func main() {
	root := context.Background()
	fmt.Println("开始 mainTask...")
	mainTask(root)
	fmt.Println("main 结束")
}
