-
Notifications
You must be signed in to change notification settings - Fork 1
/
errable.go
63 lines (49 loc) · 1.35 KB
/
errable.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
/*
© 2023–present Harald Rudell <harald.rudell@gmail.com> (https://haraldrudell.github.io/haraldrudell/)
ISC License
*/
package parl
import "sync"
// Invoker allows to invoke a function returning error as a function with no return value. Thread Safe
// - panics while executing FuncErr are recovered
//
// Thread-safe
type Invoker struct {
funcErr func() (err error)
invokeLock sync.RWMutex
isDone bool
result InvokeResult
}
type InvokeResult struct {
IsPanic bool
Err error
}
// NewInvoker returns an object that can invoke a function returning error as a
// function with no return values. Thread-safe
func NewInvoker(funcErr func() (err error)) (invoker *Invoker) {
return &Invoker{funcErr: funcErr}
}
// Func invokes the function returning error storing results in its fields
func (i *Invoker) Func() {
isPanic, err := RecoverInvocationPanicErr(i.funcErr)
i.invokeLock.Lock()
defer i.invokeLock.RUnlock()
i.isDone = true
i.result.IsPanic = isPanic
i.result.Err = err
}
func (i *Invoker) Result() (isDone, isPanic bool, err error) {
i.invokeLock.RLock()
defer i.invokeLock.RUnlock()
isDone = i.isDone
isPanic = i.result.IsPanic
err = i.result.Err
return
}
func (i *Invoker) InvokeResult() (invokeResult *InvokeResult) {
i.invokeLock.RLock()
defer i.invokeLock.RUnlock()
var copy = i.result
invokeResult = ©
return
}