@@ -11,6 +11,10 @@ import (
11
11
12
12
const DeadlockDetection = 40 * time .Second
13
13
14
+ type CoroutineCreator interface {
15
+ NewCoroutine (ctx Context , fn func (Context ) error )
16
+ }
17
+
14
18
type Coroutine interface {
15
19
// Execute continues execution of a blocked corouting and waits until
16
20
// it is finished or blocked again
@@ -28,7 +32,9 @@ type Coroutine interface {
28
32
29
33
Error () error
30
34
31
- SetScheduler (s Scheduler )
35
+ SetCoroutineCreator (creator CoroutineCreator )
36
+
37
+ SetPanicHandler (handler func (interface {}) error )
32
38
}
33
39
34
40
type key int
@@ -47,13 +53,14 @@ type coState struct {
47
53
shouldExit atomic.Value // coroutine should exit
48
54
progress atomic.Value // did the coroutine make progress since last yield?
49
55
50
- err error
56
+ err error
57
+ panicHandler func (interface {}) error
51
58
52
59
logger logger
53
60
54
61
deadlockDetection time.Duration
55
62
56
- scheduler Scheduler
63
+ creator CoroutineCreator
57
64
}
58
65
59
66
func NewCoroutine (ctx Context , fn func (ctx Context ) error ) Coroutine {
@@ -64,7 +71,11 @@ func NewCoroutine(ctx Context, fn func(ctx Context) error) Coroutine {
64
71
defer s .finish () // Ensure we always mark the coroutine as finished
65
72
defer func () {
66
73
if r := recover (); r != nil {
67
- s .err = fmt .Errorf ("panic: %v" , r )
74
+ if s .panicHandler != nil {
75
+ s .err = s .panicHandler (r )
76
+ } else {
77
+ s .err = fmt .Errorf ("panic: %v" , r )
78
+ }
68
79
}
69
80
}()
70
81
@@ -99,8 +110,12 @@ func (s *coState) finish() {
99
110
s .logger .Println ("finish" )
100
111
}
101
112
102
- func (s * coState ) SetScheduler (scheduler Scheduler ) {
103
- s .scheduler = scheduler
113
+ func (s * coState ) SetCoroutineCreator (creator CoroutineCreator ) {
114
+ s .creator = creator
115
+ }
116
+
117
+ func (s * coState ) SetPanicHandler (handler func (interface {}) error ) {
118
+ s .panicHandler = handler
104
119
}
105
120
106
121
func (s * coState ) Finished () bool {
0 commit comments