|
21 | 21 | package workflow |
22 | 22 |
|
23 | 23 | import ( |
| 24 | + "github.com/opentracing/opentracing-go" |
| 25 | + |
24 | 26 | "go.uber.org/cadence/internal" |
25 | 27 | ) |
26 | 28 |
|
@@ -76,3 +78,78 @@ func WithValue(parent Context, key interface{}, val interface{}) Context { |
76 | 78 | func NewDisconnectedContext(parent Context) (ctx Context, cancel CancelFunc) { |
77 | 79 | return internal.NewDisconnectedContext(parent) |
78 | 80 | } |
| 81 | + |
| 82 | +// GetSpanContext returns the [opentracing.SpanContext] from [Context]. |
| 83 | +// Returns nil if tracer is not set in [go.uber.org/cadence/worker.Options]. |
| 84 | +// |
| 85 | +// Note: If tracer is set, we already activate a span for each workflow. |
| 86 | +// This SpanContext will be passed to the activities and child workflows to start new spans. |
| 87 | +// |
| 88 | +// Example Usage: |
| 89 | +// |
| 90 | +// span := GetSpanContext(ctx) |
| 91 | +// if span != nil { |
| 92 | +// span.SetTag("foo", "bar") |
| 93 | +// } |
| 94 | +func GetSpanContext(ctx Context) opentracing.SpanContext { |
| 95 | + return internal.GetSpanContext(ctx) |
| 96 | +} |
| 97 | + |
| 98 | +// WithSpanContext returns [Context] with override [opentracing.SpanContext]. |
| 99 | +// This is useful to modify baggage items of current workflow and pass it to activities and child workflows. |
| 100 | +// |
| 101 | +// Example Usage: |
| 102 | +// |
| 103 | +// func goodWorkflow(ctx Context) (string, error) { |
| 104 | +// // start a short lived new workflow span within SideEffect to avoid duplicate span creation during replay |
| 105 | +// type spanActivationResult struct { |
| 106 | +// Carrier map[string]string // exported field so it's json encoded |
| 107 | +// Err error |
| 108 | +// } |
| 109 | +// resultValue := workflow.SideEffect(ctx, func(ctx workflow.Context) interface{} { |
| 110 | +// wSpan := w.tracer.StartSpan("workflow-operation-with-new-span", opentracing.ChildOf(workflow.GetSpanContext(ctx))) |
| 111 | +// defer wSpan.Finish() |
| 112 | +// wSpan.SetBaggageItem("some-key", "some-value") |
| 113 | +// carrier := make(map[string]string) |
| 114 | +// err := w.tracer.Inject(wSpan.Context(), opentracing.TextMap, opentracing.TextMapCarrier(carrier)) |
| 115 | +// return spanActivationResult{Carrier: carrier, Err: err} |
| 116 | +// }) |
| 117 | +// var activationResult spanActivationResult |
| 118 | +// if err := resultValue.Get(&activationResult); err != nil { |
| 119 | +// return nil, fmt.Errorf("failed to decode span activation result: %v", err) |
| 120 | +// } |
| 121 | +// if activationResult.Err != nil { |
| 122 | +// return nil, fmt.Errorf("failed to activate new span: %v", activationResult.Err) |
| 123 | +// } |
| 124 | +// spanContext, err := w.tracer.Extract(opentracing.TextMap, opentracing.TextMapCarrier(activationResult.Carrier)) |
| 125 | +// if err != nil { |
| 126 | +// return nil, fmt.Errorf("failed to extract span context: %v", err) |
| 127 | +// } |
| 128 | +// ctx = workflow.WithSpanContext(ctx, spanContext) |
| 129 | +// var activityFooResult string |
| 130 | +// aCtx := workflow.WithActivityOptions(ctx, opts) |
| 131 | +// err = workflow.ExecuteActivity(aCtx, activityFoo).Get(aCtx, &activityFooResult) |
| 132 | +// return activityFooResult, err |
| 133 | +// } |
| 134 | +// |
| 135 | +// Bad Example: |
| 136 | +// |
| 137 | +// func badWorkflow(ctx Context) (string, error) { |
| 138 | +// // start a new workflow span for EVERY REPLAY |
| 139 | +// wSpan := opentracing.StartSpan("workflow-operation", opentracing.ChildOf(GetSpanContext(ctx))) |
| 140 | +// wSpan.SetBaggageItem("some-key", "some-value") |
| 141 | +// // pass the new span context to activity |
| 142 | +// ctx = WithSpanContext(ctx, wSpan.Context()) |
| 143 | +// aCtx := workflow.WithActivityOptions(ctx, opts) |
| 144 | +// var activityFooResult string |
| 145 | +// err := ExecuteActivity(aCtx, activityFoo).Get(aCtx, &activityFooResult) |
| 146 | +// wSpan.Finish() |
| 147 | +// return activityFooResult, err |
| 148 | +// } |
| 149 | +// |
| 150 | +// func activityFoo(ctx Context) (string, error) { |
| 151 | +// return "activity-foo-result", nil |
| 152 | +// } |
| 153 | +func WithSpanContext(ctx Context, spanContext opentracing.SpanContext) Context { |
| 154 | + return internal.WithSpanContext(ctx, spanContext) |
| 155 | +} |
0 commit comments