blob: 583025ce531cb6df1c0a97373aa4a64d1c092c00 [file] [log] [blame]
Girish Kumar2ed051b2020-07-28 16:35:25 +00001package grpc_ctxtags
2
3import (
4 "context"
5)
6
7type ctxMarker struct{}
8
9var (
10 // ctxMarkerKey is the Context value marker used by *all* logging middleware.
11 // The logging middleware object must interf
12 ctxMarkerKey = &ctxMarker{}
13 // NoopTags is a trivial, minimum overhead implementation of Tags for which all operations are no-ops.
14 NoopTags = &noopTags{}
15)
16
17// Tags is the interface used for storing request tags between Context calls.
18// The default implementation is *not* thread safe, and should be handled only in the context of the request.
19type Tags interface {
20 // Set sets the given key in the metadata tags.
21 Set(key string, value interface{}) Tags
22 // Has checks if the given key exists.
23 Has(key string) bool
24 // Values returns a map of key to values.
25 // Do not modify the underlying map, please use Set instead.
26 Values() map[string]interface{}
27}
28
29type mapTags struct {
30 values map[string]interface{}
31}
32
33func (t *mapTags) Set(key string, value interface{}) Tags {
34 t.values[key] = value
35 return t
36}
37
38func (t *mapTags) Has(key string) bool {
39 _, ok := t.values[key]
40 return ok
41}
42
43func (t *mapTags) Values() map[string]interface{} {
44 return t.values
45}
46
47type noopTags struct{}
48
49func (t *noopTags) Set(key string, value interface{}) Tags {
50 return t
51}
52
53func (t *noopTags) Has(key string) bool {
54 return false
55}
56
57func (t *noopTags) Values() map[string]interface{} {
58 return nil
59}
60
61// Extracts returns a pre-existing Tags object in the Context.
62// If the context wasn't set in a tag interceptor, a no-op Tag storage is returned that will *not* be propagated in context.
63func Extract(ctx context.Context) Tags {
64 t, ok := ctx.Value(ctxMarkerKey).(Tags)
65 if !ok {
66 return NoopTags
67 }
68
69 return t
70}
71
72func setInContext(ctx context.Context, tags Tags) context.Context {
73 return context.WithValue(ctx, ctxMarkerKey, tags)
74}
75
76func newTags() Tags {
77 return &mapTags{values: make(map[string]interface{})}
78}