github.com/go-board/x-go@v0.1.2-0.20220610024734-db1323f6cb15/metadata/metadata.go (about) 1 package metadata 2 3 import ( 4 "context" 5 "strings" 6 ) 7 8 // Metadata is an attribute list, and will be propagation to the whole call chain. 9 // In process, will inject to context.Context. 10 // Cross process, will serialize to header for HTTPHeader/GRPC. 11 type Metadata map[string]string 12 13 // Clone return the copy of original Metadata 14 func (md Metadata) Clone() Metadata { 15 newMd := make(Metadata, len(md)) 16 for k, v := range md { 17 newMd[k] = v 18 } 19 return newMd 20 } 21 22 func (md Metadata) ValueList(key string) []string { return strings.Split(md[key], ",") } 23 24 var metadataKey = struct{}{} 25 26 // FromContext retrieve Metadata from context.Context with default metadataKey. 27 // 28 // 使用默认的key从context.Context中取出Metadata,如果不存在默认的key,会发生panic 29 func FromContext(ctx context.Context) Metadata { 30 return FromContextKey(ctx, metadataKey) 31 } 32 33 // FromContextKey retrieve Metadata from context.Context with given key, if nil, panic. 34 // 35 // 使用给定的key从context.Context中取出Metadata, 如果不存在给定的key,会发生panic 36 func FromContextKey(ctx context.Context, key interface{}) Metadata { 37 return ctx.Value(key).(Metadata) 38 } 39 40 // TryFromContext retrieve Metadata from context.Context with default metadataKey. 41 // 42 // 尝试使用默认的key从context.Context中取出Metadata 43 func TryFromContext(ctx context.Context) (Metadata, bool) { 44 return TryFromContextKey(ctx, metadataKey) 45 } 46 47 // TryFromContextKey retrieve Metadata from context.Context with given key. 48 // 49 // 尝试使用给定的key从context.Context中取出Metadata 50 func TryFromContextKey(ctx context.Context, key interface{}) (Metadata, bool) { 51 val := ctx.Value(key) 52 if val == nil { 53 return nil, false 54 } 55 md, ok := val.(Metadata) 56 return md, ok 57 } 58 59 // IntoContext will append Metadata to context.Context use default metadataKey, ignore previous one. 60 // 61 // 使用默认的metadataKey讲Metadata注入到context.Context中,会忽略掉之前设置的。 62 func IntoContext(ctx context.Context, md Metadata) context.Context { 63 return IntoContextKey(ctx, metadataKey, md) 64 } 65 66 // IntoContextKey will append Metadata to context.Context use given key, ignore previous one. 67 // 68 // 使用给定的key讲Metadata注入到context.Context中, 会忽略掉之前设置的。 69 func IntoContextKey(ctx context.Context, key interface{}, md Metadata) context.Context { 70 return context.WithValue(ctx, key, md) 71 } 72 73 // MergeIntoContext will append Metadata to context.Context use default metadataKey, if has previous one, merge then update. 74 // 75 // 使用默认的metadataKey讲Metadata注入到context.Context中,如果存在上一个,先合并再更新 76 func MergeIntoContext(ctx context.Context, md Metadata) context.Context { 77 oldOne, ok := TryFromContext(ctx) 78 if !ok { 79 return IntoContext(ctx, md) 80 } 81 for k, v := range oldOne { 82 md[k] = v 83 } 84 return IntoContext(ctx, md) 85 } 86 87 // MergeIntoContextKey will append Metadata to context.Context use default metadataKey, if has previous one, merge then update. 88 // 89 // 使用给定的keyey讲Metadata注入到context.Context中,如果存在上一个,先合并再更新 90 func MergeIntoContextKey(ctx context.Context, key interface{}, md Metadata) context.Context { 91 oldOne, ok := TryFromContextKey(ctx, key) 92 if !ok { 93 return IntoContextKey(ctx, key, md) 94 } 95 for k, v := range oldOne { 96 md[k] = v 97 } 98 return IntoContextKey(ctx, key, md) 99 }