Repository navigation
Expand file tree
/
Copy pathscope_context.go
More file actions
108 lines (92 loc) · 2.79 KB
/
Copy pathscope_context.go
File metadata and controls
108 lines (92 loc) · 2.79 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
package sentry
import (
"context"
"sync"
"github.com/getsentry/sentry-go/internal/contextkey"
)
type scopeContextKey struct{}
type clientContextKey = contextkey.Client
type requestContextKey struct{}
// RequestContextKey is the key used to store the current request object in a
// capture context.
var RequestContextKey requestContextKey
// globalScope is the process-wide global scope.
var globalScope = NewScope()
var (
globalClientMu sync.RWMutex
globalClient *Client
)
// GlobalScope returns the process-wide global scope.
func GlobalScope() *Scope {
return globalScope
}
// ScopeFromContext returns the scope carried by ctx, or nil when there is none.
func ScopeFromContext(ctx context.Context) *Scope {
if ctx == nil {
return nil
}
scope, _ := ctx.Value(scopeContextKey{}).(*Scope)
return scope
}
func scopeAndTraceFallback(ctx, fallback context.Context) (*Scope, context.Context) {
if scope := ScopeFromContext(ctx); scope != nil {
return scope, nil
}
return ScopeFromContext(fallback), fallback
}
// ContextWithScope returns a context carrying scope. A nil scope leaves ctx unchanged.
func ContextWithScope(ctx context.Context, scope *Scope) context.Context {
if scope == nil {
return ctx
}
return context.WithValue(ctx, scopeContextKey{}, scope)
}
// ContextWithClient returns a derived context that routes telemetry through
// client without changing its scope. A nil client leaves ctx unchanged.
func ContextWithClient(ctx context.Context, client *Client) context.Context {
if client == nil {
return ctx
}
return context.WithValue(ctx, clientContextKey{}, client)
}
// WithScope returns a derived context and a forked scope.
// It clones a carried scope, or starts an empty scope with a new propagation
// context when ctx does not carry one.
func WithScope(ctx context.Context) (context.Context, *Scope) {
var scope *Scope
if parent := ScopeFromContext(ctx); parent != nil {
scope = parent.Clone()
} else {
scope = NewScope()
}
return ContextWithScope(ctx, scope), scope
}
// ClientFromContext returns the client attached to ctx, or the global client.
func ClientFromContext(ctx context.Context) *Client {
if ctx != nil {
if client, ok := ctx.Value(clientContextKey{}).(*Client); ok {
return client
}
}
return normalizeClient(globalClientSnapshot())
}
// clientFromContexts retains the construction client unless emission binds one.
func clientFromContexts(ctx, fallback context.Context) *Client {
if ctx != nil {
if client, ok := ctx.Value(clientContextKey{}).(*Client); ok {
return client
}
}
return ClientFromContext(fallback)
}
func setGlobalClient(client *Client) {
globalClientMu.Lock()
globalClient = client
globalClientMu.Unlock()
}
func globalClientSnapshot() *Client {
globalClientMu.RLock()
client := globalClient
globalClientMu.RUnlock()
return client
}