@@ -14,12 +14,34 @@ import (
1414type withCustomAttributes struct {}
1515
1616func AttributesFrom (ctx context.Context ) map [string ]string {
17- return binding .GetOrDefaultFromCtx (ctx , withCustomAttributes {}, make (map [string ]string )).(map [string ]string )
17+ ctxVal := binding .GetOrDefaultFromCtx (ctx , withCustomAttributes {}, nil )
18+ if ctxVal == nil {
19+ return make (map [string ]string , 0 )
20+ }
21+
22+ m := ctxVal .(map [string ]string )
23+
24+ // Since it is possible that we get the same map from one ctx multiple times
25+ // we need to make sure, that it is race free to modify said map.
26+ cp := make (map [string ]string , len (m ))
27+ for k , v := range m {
28+ cp [k ] = v
29+ }
30+ return cp
1831}
1932
2033// WithCustomAttributes sets Message Attributes without any CloudEvent logic.
2134// Note that this function is not intended for CloudEvent Extensions or any `ce-`-prefixed Attributes.
2235// For these please see `Event` and `Event.SetExtension`.
2336func WithCustomAttributes (ctx context.Context , attrs map [string ]string ) context.Context {
37+ if attrs != nil {
38+ // Since it is likely that read the map in another goroutine
39+ // ensure that modifying attrs is race free in any case.
40+ cp := make (map [string ]string , len (attrs ))
41+ for k , v := range attrs {
42+ cp [k ] = v
43+ }
44+ attrs = cp
45+ }
2446 return context .WithValue (ctx , withCustomAttributes {}, attrs )
2547}
0 commit comments