-
Notifications
You must be signed in to change notification settings - Fork 0
/
goroutine.go
71 lines (64 loc) · 1.22 KB
/
goroutine.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
package safe
import (
"context"
"log"
"runtime/debug"
)
type (
RecoverHandler func(r interface{})
DoFunc func()
DoCtxFunc func(ctx context.Context)
)
var DefaultRecoverHandler RecoverHandler = func(r interface{}) {
log.Printf("Recovered in goroutine: %s, stack: %s\n", r, debug.Stack())
}
// Go starts a recoverable goroutine.
//
// Example:
//
// safe.Go(
// func() { ... },
// )
func Go(do DoFunc) {
GoR(do, DefaultRecoverHandler)
}
// GoR starts a recoverable goroutine using given recover handler.
//
// Example:
//
// safe.GoR(
// func() { ... },
// customRecoverHandler
// )
func GoR(do DoFunc, handlers ...RecoverHandler) {
go func() {
defer HandleCrash(handlers...)
do()
}()
}
// DefaultHandleCrash simply catches a crash with the default recover handler.
//
// Example:
//
// go func() {
// defer DefaultHandleCrash()
// ...
// }()
func DefaultHandleCrash() {
HandleCrash(DefaultRecoverHandler)
}
// HandleCrash catches a crash with the custom recover handlers.
//
// Example:
//
// go func() {
// defer HandleCrash(customRecoverHandler)
// ...
// }()
func HandleCrash(handlers ...RecoverHandler) {
if r := recover(); r != nil {
for _, handler := range handlers {
handler(r)
}
}
}