log: lazy evaluate without lock

This commit is contained in:
Zhao Li 2018-09-14 10:05:16 +08:00
parent 20cb3e3549
commit 459cc8fb80

View file

@ -158,12 +158,15 @@ func RotatingFileHandler(path string, limit uint, formatter Format) (Handler, er
if counter == nil { if counter == nil {
counter = new(countingWriter) counter = new(countingWriter)
} }
h := LazyHandler(FuncHandler(func(r *Record) error { h := FuncHandler(func(r *Record) error {
_, err := counter.Write(formatter.Format(r)) _, err := counter.Write(formatter.Format(r))
return err return err
})) })
return FuncHandler(func(r *Record) error { return FuncHandler(func(r *Record) error {
// lazy evaluate, this needs no lock.
lazyEvaluateRecord(r)
counter.Lock() counter.Lock()
defer counter.Unlock() defer counter.Unlock()
if counter.count > limit { if counter.count > limit {
@ -389,33 +392,36 @@ func BufferedHandler(bufSize int, h Handler) Handler {
// it if you write your own Handler. // it if you write your own Handler.
func LazyHandler(h Handler) Handler { func LazyHandler(h Handler) Handler {
return FuncHandler(func(r *Record) error { return FuncHandler(func(r *Record) error {
// go through the values (odd indices) and reassign lazyEvaluateRecord(r)
// the values of any lazy fn to the result of its execution
hadErr := false
for i := 1; i < len(r.Ctx); i += 2 {
lz, ok := r.Ctx[i].(Lazy)
if ok {
v, err := evaluateLazy(lz)
if err != nil {
hadErr = true
r.Ctx[i] = err
} else {
if cs, ok := v.(stack.CallStack); ok {
v = cs.TrimBelow(r.Call).TrimRuntime()
}
r.Ctx[i] = v
}
}
}
if hadErr {
r.Ctx = append(r.Ctx, errorKey, "bad lazy")
}
return h.Log(r) return h.Log(r)
}) })
} }
func lazyEvaluateRecord(r *Record) {
// go through the values (odd indices) and reassign
// the values of any lazy fn to the result of its execution
hadErr := false
for i := 1; i < len(r.Ctx); i += 2 {
lz, ok := r.Ctx[i].(Lazy)
if ok {
v, err := evaluateLazy(lz)
if err != nil {
hadErr = true
r.Ctx[i] = err
} else {
if cs, ok := v.(stack.CallStack); ok {
v = cs.TrimBelow(r.Call).TrimRuntime()
}
r.Ctx[i] = v
}
}
}
if hadErr {
r.Ctx = append(r.Ctx, errorKey, "bad lazy")
}
}
func evaluateLazy(lz Lazy) (interface{}, error) { func evaluateLazy(lz Lazy) (interface{}, error) {
t := reflect.TypeOf(lz.Fn) t := reflect.TypeOf(lz.Fn)