-
Notifications
You must be signed in to change notification settings - Fork 0
/
defer.go
77 lines (64 loc) · 1.39 KB
/
defer.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
package yaft
import (
"time"
)
// Defer is used to represent an action that may occur in the deferLog
type Defer interface {
Error() error
}
// ApplyDefer is used for Apply() and can returns the FSM response
type ApplyDefer interface {
Defer
Response() interface{}
}
// DeferError can be embedded to allow a deferLog
// to provide an error in the deferLog
type DeferError struct {
err error
errCh chan error
responded bool
}
func (d *DeferError) init() {
d.errCh = make(chan error, 1)
}
func (d *DeferError) Error() error {
if d.err != nil {
return d.err
}
if d.errCh == nil {
panic("waiting for response on nil channel")
}
d.err = <-d.errCh
return d.err
}
func (d *DeferError) Response() interface{} {
return nil
}
// DeferLog is used to apply a log entry and waits until
// the log is considered committed
type DeferLog struct {
DeferError
log Log
quorum majorityQuorum
response interface{}
dispatch time.Time
}
func (d *DeferLog) Error() error {
return d.DeferError.Error()
}
func (d *DeferLog) Response() interface{} {
return d.response
}
// MajorityQuorum is used by Apply transactions and requires
// a simple majority of nodes
type majorityQuorum struct {
count int
votesNeeded int
}
func (m *majorityQuorum) Commit() bool {
m.count++
return m.count >= m.votesNeeded
}
func (m *majorityQuorum) IsCommitted() bool {
return m.count >= m.votesNeeded
}