// TextMapCarrier allows the use of regular map[string]string// as both TextMapWriter and TextMapReader.typeTextMapCarriermap[string]string// HTTPHeadersCarrier satisfies both TextMapWriter and TextMapReader.//// Example usage for server side://// carrier := opentracing.HTTPHeadersCarrier(httpReq.Header)// clientContext, err := tracer.Extract(opentracing.HTTPHeaders, carrier)//// Example usage for client side://// carrier := opentracing.HTTPHeadersCarrier(httpReq.Header)// err := tracer.Inject(// span.Context(),// opentracing.HTTPHeaders,// carrier)//typeHTTPHeadersCarrierhttp.Header
// TextMapWriter is the Inject() carrier for the TextMap builtin format. With// it, the caller can encode a SpanContext for propagation as entries in a map// of unicode strings.typeTextMapWriterinterface {// Set a key:value pair to the carrier. Multiple calls to Set() for the// same key leads to undefined behavior.//// NOTE: The backing store for the TextMapWriter may contain data unrelated// to SpanContext. As such, Inject() and Extract() implementations that// call the TextMapWriter and TextMapReader interfaces must agree on a// prefix or other convention to distinguish their own key:value pairs.Set(key, val string)}// TextMapReader is the Extract() carrier for the TextMap builtin format. With it,// the caller can decode a propagated SpanContext as entries in a map of// unicode strings.typeTextMapReaderinterface {// ForeachKey returns TextMap contents via repeated calls to the `handler`// function. If any call to `handler` returns a non-nil error, ForeachKey// terminates and returns that error.//// NOTE: The backing store for the TextMapReader may contain data unrelated// to SpanContext. As such, Inject() and Extract() implementations that// call the TextMapWriter and TextMapReader interfaces must agree on a// prefix or other convention to distinguish their own key:value pairs.//// The "foreach" callback pattern reduces unnecessary copying in some cases// and also allows implementations to hold locks while the map is read.ForeachKey(handler func(key, val string) error) error}
我们接下来来实现一下两个接口,采用一个自定义的carrier。
// MDCarrier custome carriertypeMDCarrierstruct {metadata.MD}// ForeachKey conforms to the TextMapReader interface.// 这里必须要实现这个 TextMapReader 这个接口// TextMapReader is the Extract() carrier for the TextMap builtin format. With it,// the caller can decode a propagated SpanContext as entries in a map of// unicode strings.//type TextMapReader interface {// // ForeachKey returns TextMap contents via repeated calls to the `handler`// // function. If any call to `handler` returns a non-nil error, ForeachKey// // terminates and returns that error.// //// // NOTE: The backing store for the TextMapReader may contain data unrelated// // to SpanContext. As such, Inject() and Extract() implementations that// // call the TextMapWriter and TextMapReader interfaces must agree on a// // prefix or other convention to distinguish their own key:value pairs.// //// // The "foreach" callback pattern reduces unnecessary copying in some cases// // and also allows implementations to hold locks while the map is read.// ForeachKey(handler func(key, val string) error) error//}func (m MDCarrier) ForeachKey(handler func(key, val string) error) error {for k, strs :=range m.MD {for _, v :=range strs {if err := handler(k, v); err !=nil {return err } } }returnnil}// Set implements Set() of opentracing.TextMapWriter// 这里也必须要实现// TextMapWriter is the Inject() carrier for the TextMap builtin format. With// it, the caller can encode a SpanContext for propagation as entries in a map// of unicode strings.//type TextMapWriter interface {// // Set a key:value pair to the carrier. Multiple calls to Set() for the// // same key leads to undefined behavior.// //// // NOTE: The backing store for the TextMapWriter may contain data unrelated// // to SpanContext. As such, Inject() and Extract() implementations that// // call the TextMapWriter and TextMapReader interfaces must agree on a// // prefix or other convention to distinguish their own key:value pairs.// Set(key, val string)//}func (m MDCarrier) Set(key, val string) { m.MD[key] =append(m.MD[key], val)}