-
Notifications
You must be signed in to change notification settings - Fork 13
/
safe.go
82 lines (72 loc) · 1.56 KB
/
safe.go
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
package sturdyc
import (
"context"
"errors"
"fmt"
)
// safeGo is a helper that prevents panics in any of the goroutines
// that are running in the background from crashing the process.
func (c *Client[T]) safeGo(fn func()) {
go func() {
defer func() {
if err := recover(); err != nil {
c.log.Error(fmt.Sprintf("sturdyc: panic recovered: %v", err))
}
}()
fn()
}()
}
func wrap[T, V any](fetchFn FetchFn[V]) FetchFn[T] {
return func(ctx context.Context) (T, error) {
res, err := fetchFn(ctx)
if err != nil {
var zero T
return zero, err
}
val, ok := any(res).(T)
if !ok {
var zero T
return zero, ErrInvalidType
}
return val, nil
}
}
func unwrap[V, T any](val T, err error) (V, error) {
if err != nil {
var zero V
return zero, err
}
v, ok := any(val).(V)
if !ok {
return v, ErrInvalidType
}
return v, err
}
func wrapBatch[T, V any](fetchFn BatchFetchFn[V]) BatchFetchFn[T] {
return func(ctx context.Context, ids []string) (map[string]T, error) {
resV, err := fetchFn(ctx, ids)
if err != nil && !errors.Is(err, errOnlyDistributedRecords) {
return map[string]T{}, err
}
resT := make(map[string]T, len(resV))
for id, v := range resV {
val, ok := any(v).(T)
if !ok {
return resT, ErrInvalidType
}
resT[id] = val
}
return resT, err
}
}
func unwrapBatch[V, T any](values map[string]T, err error) (map[string]V, error) {
vals := make(map[string]V, len(values))
for id, v := range values {
val, ok := any(v).(V)
if !ok {
return vals, ErrInvalidType
}
vals[id] = val
}
return vals, err
}