github.com/git-amp/amp-sdk-go@v0.7.5/stdlib/task/support.go (about) 1 package task 2 3 import ( 4 "bytes" 5 "io" 6 "strings" 7 "time" 8 ) 9 10 // Periodically calls PrintContextTree() to the context's logger. 11 func PrintTreePeriodically(ctx Context, period time.Duration, verboseLevel int32) { 12 block := [32]byte{} 13 var text []byte 14 buf := bytes.Buffer{} 15 buf.Grow(256) 16 17 ticker := time.NewTicker(period) 18 for running := true; running; { 19 select { 20 case <-ticker.C: 21 { 22 PrintContextTree(ctx, &buf, verboseLevel) 23 changed := false 24 R := buf.Len() 25 if R != len(text) { 26 if cap(text) < R { 27 text = make([]byte, R, (R+0x1FF)&^0x1FF) 28 } else { 29 text = text[:R] 30 } 31 changed = true 32 } 33 for pos := 0; pos < R; { 34 n, _ := buf.Read(block[:]) 35 if n == 0 { 36 break 37 } 38 if !changed { 39 changed = !bytes.Equal(block[:n], text[pos:pos+n]) 40 } 41 if changed { 42 copy(text[pos:], block[:n]) 43 } 44 pos += n 45 } 46 if changed { 47 ctx.Info(verboseLevel, string(text)) 48 } 49 buf.Reset() 50 } 51 case <-ctx.Closing(): 52 running = false 53 } 54 } 55 ticker.Stop() 56 } 57 58 // Writes pretty and indented debug state info of a given verbosity level. 59 // If out == nil, the text output is instead directed to this context's logger.Info() 60 func PrintContextTree(ctx Context, out io.Writer, verboseLevel int32) { 61 buf := new(strings.Builder) 62 buf.WriteString("task.Context tree:\n") 63 64 var prefixBuf [256]rune 65 printContextTree(ctx, buf, 0, prefixBuf[:0], true) 66 outStr := buf.String() 67 if out != nil { 68 out.Write([]byte(outStr)) 69 } else { 70 ctx.Info(verboseLevel, outStr) 71 } 72 }