forked from deis/builder
/
circuit.go
66 lines (56 loc) · 1.9 KB
/
circuit.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
package sshd
import (
"fmt"
"sync/atomic"
)
// CircuitState represents the state of a Circuit.
type CircuitState uint32
const (
// OpenState indicates that the circuit is in the open state, and thus non-functional.
OpenState CircuitState = 0
// ClosedState indicates that the circuit is in the closed state, and thus functional.
ClosedState CircuitState = 1
)
// String is the fmt.Stringer interface implementation.
func (c CircuitState) String() string {
if c == OpenState {
return "OPEN"
} else if c == ClosedState {
return "CLOSED"
} else {
return fmt.Sprintf("Unknown (%d)", c.toUint32())
}
}
func (c CircuitState) toUint32() uint32 {
return uint32(c)
}
// Circuit is a concurrency-safe data structure that can take one of two states at any point in
// time:
//
// - OpenState - non functional
// - ClosedState - functional
//
// The circuit is intended as a point-in-time indicator of functionality. It has no backoff
// mechanism, jitter or ramp-up/ramp-down functionality.
type Circuit struct {
bit uint32
}
// NewCircuit creates a new circuit, in the open (non-functional) state.
func NewCircuit() *Circuit {
return &Circuit{bit: OpenState.toUint32()}
}
// State returns the current state of the circuit. Note that concurrent modifications may be
// happening, so the state may be different than what's returned.
func (c *Circuit) State() CircuitState {
return CircuitState(atomic.LoadUint32(&c.bit))
}
// Close closes the circuit if it wasn't already closed. Returns true if it had to be closed,
// false if it was already closed.
func (c *Circuit) Close() bool {
return atomic.CompareAndSwapUint32(&c.bit, OpenState.toUint32(), ClosedState.toUint32())
}
// Open opens the circuit if it wasn't already closed. Returns true if it had to be opened,
// false if it was already open.
func (c *Circuit) Open() bool {
return atomic.CompareAndSwapUint32(&c.bit, ClosedState.toUint32(), OpenState.toUint32())
}