trpc.group/trpc-go/trpc-go@v1.0.3/rpcz/context.go (about)

     1  //
     2  //
     3  // Tencent is pleased to support the open source community by making tRPC available.
     4  //
     5  // Copyright (C) 2023 THL A29 Limited, a Tencent company.
     6  // All rights reserved.
     7  //
     8  // If you have downloaded a copy of the tRPC source code from Tencent,
     9  // please note that tRPC source code is licensed under the  Apache 2.0 License,
    10  // A copy of the Apache 2.0 License is included in this file.
    11  //
    12  //
    13  
    14  package rpcz
    15  
    16  import "context"
    17  
    18  type (
    19  	spanKey    struct{}
    20  	notSpanKey struct{}
    21  )
    22  
    23  // SpanFromContext returns Span from ctx.
    24  // If no Span isn't currently set in ctx, returns GlobalRPCZ.
    25  func SpanFromContext(ctx context.Context) Span {
    26  	if s, ok := ctx.Value(spanKey{}).(Span); ok {
    27  		return s
    28  	}
    29  	return GlobalRPCZ
    30  }
    31  
    32  // ContextWithSpan returns a copy of parent with span set as the current Span.
    33  func ContextWithSpan(ctx context.Context, span Span) context.Context {
    34  	return context.WithValue(ctx, spanKey{}, span)
    35  }
    36  
    37  // NewSpanContext creates a new span and binds it to a new ctx by combining SpanFromContext, Span.NewChildSpan and
    38  // ContextWithSpan. It returns the original ctx if new span is the same as original one to avoid unnecessary valueCtx.
    39  // Ender used to end this span immediately,and doesn't wait for related work to stop.
    40  // Ender doesn't end context.Context.
    41  func NewSpanContext(ctx context.Context, name string) (Span, Ender, context.Context) {
    42  	span := SpanFromContext(ctx)
    43  	newSpan, end := span.NewChild(name)
    44  	if newSpan == span {
    45  		return newSpan, end, ctx
    46  	}
    47  	return newSpan, end, ContextWithSpan(ctx, newSpan)
    48  }