generated from bool64/go-template
-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathcontext.go
More file actions
89 lines (72 loc) · 2.35 KB
/
context.go
File metadata and controls
89 lines (72 loc) · 2.35 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
package cache
import (
"context"
"time"
)
type (
skipReadCtxKey struct{}
ttlCtxKey struct{}
)
// WithTTL adds cache time to live information to context.
//
// If there is already ttl in context and updateExisting is true, then ttl value in original context will be updated.
//
// Updating existing ttl can be useful if ttl information is only available internally during cache value build,
// in such a case value builder can communicate ttl to external cache backend.
// For example cache ttl can be derived from HTTP response cache headers of value source.
//
// When existing ttl is updated minimal non-zero value is kept.
// This is necessary to unite ttl requirements of multiple parties.
func WithTTL(ctx context.Context, ttl time.Duration, updateExisting bool) context.Context {
if updateExisting {
if existing, ok := ctx.Value(ttlCtxKey{}).(*time.Duration); ok {
if *existing == 0 || *existing > ttl {
*existing = ttl
}
return ctx
}
}
return context.WithValue(ctx, ttlCtxKey{}, &ttl)
}
// TTL retrieves cache time to live from context, zero value is returned by default.
func TTL(ctx context.Context) time.Duration {
ttl, ok := ctx.Value(ttlCtxKey{}).(*time.Duration)
if ok {
return *ttl
}
return 0
}
// WithSkipRead returns context with cache read ignored.
//
// With such context cache.Reader should always return ErrNotFound discarding cached value.
func WithSkipRead(ctx context.Context) context.Context {
return context.WithValue(ctx, skipReadCtxKey{}, true)
}
// withoutSkipRead returns context with SkipRead flag disabled.
func withoutSkipRead(ctx context.Context) context.Context {
if SkipRead(ctx) {
return context.WithValue(ctx, skipReadCtxKey{}, false)
}
return ctx
}
// SkipRead returns true if cache read is ignored in context.
func SkipRead(ctx context.Context) bool {
v, ok := ctx.Value(skipReadCtxKey{}).(bool)
return ok && v
}
// detachedContext exposes parent values, but suppresses parent cancellation.
type detachedContext struct {
parent context.Context //nolint:containedctx // This wrapping is here on purpose.
}
func (d detachedContext) Deadline() (deadline time.Time, ok bool) {
return time.Time{}, false
}
func (d detachedContext) Done() <-chan struct{} {
return nil
}
func (d detachedContext) Err() error {
return nil
}
func (d detachedContext) Value(key interface{}) interface{} {
return d.parent.Value(key)
}