gorgonia.org/gorgonia@v0.9.17/x/vm/tracer.go (about)

     1  package xvm
     2  
     3  import (
     4  	"context"
     5  	"reflect"
     6  	"runtime"
     7  	"time"
     8  )
     9  
    10  // Trace the nodes states
    11  type Trace struct {
    12  	//fmt.Println(runtime.FuncForPC(reflect.ValueOf(state).Pointer()).Name())
    13  	StateFunction string
    14  	ID            int64
    15  	Start         time.Time
    16  	End           time.Time `json:",omitempty"`
    17  }
    18  
    19  type chanTracerContextKey int
    20  
    21  const (
    22  	globalTracerContextKey chanTracerContextKey = 0
    23  )
    24  
    25  // WithTracing initializes a tracing channel and adds it to the context
    26  func WithTracing(parent context.Context) (context.Context, <-chan Trace) {
    27  	c := make(chan Trace, 0)
    28  	return context.WithValue(parent, globalTracerContextKey, c), c
    29  }
    30  
    31  // CloseTracing the tracing channel to avoid context leak.
    32  // it is a nil op if context does not carry tracing information
    33  func CloseTracing(ctx context.Context) {
    34  	c := extractTracingChannel(ctx)
    35  	if c != nil {
    36  		close(c)
    37  	}
    38  }
    39  
    40  func extractTracingChannel(ctx context.Context) chan<- Trace {
    41  	if ctx == nil {
    42  		return nil
    43  	}
    44  	if c := ctx.Value(globalTracerContextKey); c != nil {
    45  		return c.(chan Trace)
    46  	}
    47  	return nil
    48  }
    49  
    50  var now = time.Now
    51  
    52  func trace(ctx context.Context, t *Trace, n *node, state stateFn) *Trace {
    53  	traceC := extractTracingChannel(ctx)
    54  	if traceC == nil {
    55  		return t
    56  	}
    57  	if t == nil {
    58  		t = &Trace{
    59  			ID:            n.id,
    60  			StateFunction: runtime.FuncForPC(reflect.ValueOf(state).Pointer()).Name(),
    61  			Start:         now(),
    62  		}
    63  	} else {
    64  		t.End = now()
    65  	}
    66  	select {
    67  	case traceC <- *t:
    68  	case <-ctx.Done():
    69  	}
    70  	return t
    71  }