Skip to content

Commit cd0e0b7

Browse files
committed
Introducing a circuit breaker for error control
1 parent 3112bd1 commit cd0e0b7

File tree

3 files changed

+55
-32
lines changed

3 files changed

+55
-32
lines changed

glide.lock

Lines changed: 8 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

glide.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package: github.com/daichirata/fluent-logger-go
22
import:
33
- package: gopkg.in/vmihailenco/msgpack.v2
4+
- package: github.com/rubyist/circuitbreaker
45
testImport:
56
- package: github.com/stretchr/testify
67
subpackages:

logger.go

Lines changed: 46 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -6,17 +6,21 @@ import (
66
"strings"
77
"sync"
88
"time"
9+
10+
"github.com/rubyist/circuitbreaker"
911
)
1012

1113
var (
12-
defaultAddress = "127.0.0.1:24224"
13-
defaultFlushInterval = 5 * time.Second
14+
defaultAddress = "127.0.0.1:24224"
15+
defaultFlushInterval = 5 * time.Second
16+
defaultFailureThreshold = int64(1)
1417
)
1518

1619
type Config struct {
1720
Address string
1821
ConnectionTimeout time.Duration
1922
FlushInterval time.Duration
23+
FailureThreshold int64
2024
}
2125

2226
func withDefaultConfig(c Config) Config {
@@ -26,23 +30,29 @@ func withDefaultConfig(c Config) Config {
2630
if c.FlushInterval == 0 {
2731
c.FlushInterval = defaultFlushInterval
2832
}
33+
if c.FailureThreshold == 0 {
34+
c.FailureThreshold = defaultFailureThreshold
35+
}
2936
return c
3037
}
3138

3239
type Logger struct {
33-
conf Config
34-
conn io.WriteCloser
35-
mu sync.Mutex
36-
buf buffer
37-
wg sync.WaitGroup
38-
done chan struct{}
40+
conf Config
41+
conn io.WriteCloser
42+
buf buffer
43+
breaker *circuit.Breaker
44+
mu sync.Mutex
45+
wg sync.WaitGroup
46+
done chan struct{}
3947
}
4048

4149
func NewLogger(c Config) (*Logger, error) {
50+
conf := withDefaultConfig(c)
4251
logger := &Logger{
43-
conf: withDefaultConfig(c),
44-
buf: newBuffer(),
45-
done: make(chan struct{}),
52+
conf: conf,
53+
buf: newBuffer(),
54+
breaker: circuit.NewConsecutiveBreaker(conf.FailureThreshold),
55+
done: make(chan struct{}),
4656
}
4757
if err := logger.connect(); err != nil {
4858
return nil, err
@@ -70,6 +80,10 @@ func (logger *Logger) PostWithTime(tag string, t time.Time, obj interface{}) err
7080
return nil
7181
}
7282

83+
func (logger *Logger) Subscribe() <-chan circuit.BreakerEvent {
84+
return logger.breaker.Subscribe()
85+
}
86+
7387
func (logger *Logger) Close() error {
7488
logger.stop()
7589
return logger.disconnect()
@@ -111,38 +125,40 @@ func (logger *Logger) disconnect() error {
111125
return err
112126
}
113127

114-
const maxWriteAttempts = 2
115-
116-
func (logger *Logger) write(messages []*Message) error {
117-
if len(messages) == 0 {
118-
return nil
119-
}
120-
var data []byte
121-
for _, m := range messages {
122-
data = append(data, m.buf.Bytes()...)
123-
}
124-
var err error
125-
for i := 0; i < maxWriteAttempts; i++ {
126-
err = logger.connect()
128+
func (logger *Logger) write(data []byte) error {
129+
err := logger.connect()
130+
if err == nil {
131+
_, err = logger.conn.Write(data)
127132
if err == nil {
128-
_, err := logger.conn.Write(data)
129-
if err == nil {
130-
break
131-
}
133+
return nil
132134
}
133-
logger.disconnect()
134135
}
136+
logger.disconnect()
135137
return err
136138
}
137139

140+
func (logger *Logger) writeWithBreaker(data []byte) error {
141+
return logger.breaker.Call(func() error {
142+
return logger.write(data)
143+
}, 0)
144+
}
145+
138146
func (logger *Logger) send() error {
139147
messages := logger.buf.Remove()
148+
if len(messages) == 0 {
149+
return nil
150+
}
140151

141-
err := logger.write(messages)
152+
var data []byte
153+
for _, m := range messages {
154+
data = append(data, m.buf.Bytes()...)
155+
}
156+
err := logger.write(data)
142157
if err != nil {
143158
logger.buf.Back(messages)
144159
return err
145160
}
161+
146162
for _, m := range messages {
147163
putMessage(m)
148164
}

0 commit comments

Comments
 (0)