1// Copyright 2023 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5// Tests user tasks, regions, and logging.
6
7//go:build ignore
8
9package main
10
11import (
12	"context"
13	"fmt"
14	"log"
15	"os"
16	"runtime/trace"
17	"time"
18)
19
20func main() {
21	baseCtx := context.Background()
22
23	// Create a task that starts and ends entirely outside of the trace.
24	ctx0, t0 := trace.NewTask(baseCtx, "parent")
25
26	// Create a task that starts before the trace and ends during the trace.
27	ctx1, t1 := trace.NewTask(ctx0, "type1")
28
29	// Start tracing.
30	if err := trace.Start(os.Stdout); err != nil {
31		log.Fatalf("failed to start tracing: %v", err)
32	}
33	t1.End()
34
35	// Create a task that starts during the trace and ends after.
36	ctx2, t2 := trace.NewTask(ctx0, "type2")
37
38	// Create a task that starts and ends during the trace.
39	ctx3, t3 := trace.NewTask(baseCtx, "type3")
40
41	// Generate some events.
42	for i := 0; i < 2; i++ {
43		do(baseCtx, 4)
44		do(ctx0, 2)
45		do(ctx1, 3)
46		do(ctx2, 6)
47		do(ctx3, 5)
48	}
49
50	// Finish up tasks according to their lifetime relative to the trace.
51	t3.End()
52	trace.Stop()
53	t2.End()
54	t0.End()
55}
56
57func do(ctx context.Context, k int) {
58	trace.Log(ctx, "log", "before do")
59
60	var t *trace.Task
61	ctx, t = trace.NewTask(ctx, "do")
62	defer t.End()
63
64	trace.Log(ctx, "log2", "do")
65
66	// Create a region and spawn more tasks and more workers.
67	trace.WithRegion(ctx, "fanout", func() {
68		for i := 0; i < k; i++ {
69			go func(i int) {
70				trace.WithRegion(ctx, fmt.Sprintf("region%d", i), func() {
71					trace.Logf(ctx, "log", "fanout region%d", i)
72					if i == 2 {
73						do(ctx, 0)
74						return
75					}
76				})
77			}(i)
78		}
79	})
80
81	// Sleep to let things happen, but also increase the chance that we
82	// advance a generation.
83	time.Sleep(10 * time.Millisecond)
84}
85