fmsg: drop messages when msgbuf is full during withhold
test / test (push) Successful in 20s
Details
test / test (push) Successful in 20s
Details
Logging functions are not expected to block. This change fixes multiple hangs where more than 64 messages are produced during withhold. Signed-off-by: Ophestra Umiker <cat@ophivana.moe>
This commit is contained in:
parent
88abcbe0b2
commit
d7df24c999
|
@ -8,6 +8,7 @@ import (
|
||||||
|
|
||||||
var (
|
var (
|
||||||
wstate atomic.Bool
|
wstate atomic.Bool
|
||||||
|
dropped atomic.Uint64
|
||||||
withhold = make(chan struct{}, 1)
|
withhold = make(chan struct{}, 1)
|
||||||
msgbuf = make(chan dOp, 64) // these ops are tiny so a large buffer is allocated for withholding output
|
msgbuf = make(chan dOp, 64) // these ops are tiny so a large buffer is allocated for withholding output
|
||||||
|
|
||||||
|
@ -29,6 +30,25 @@ func dequeue() {
|
||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// queue submits ops to msgbuf but drops messages
|
||||||
|
// when the buffer is full and dequeue is withholding
|
||||||
|
func queue(op dOp) {
|
||||||
|
select {
|
||||||
|
case msgbuf <- op:
|
||||||
|
queueSync.Add(1)
|
||||||
|
default:
|
||||||
|
// send the op anyway if not withholding
|
||||||
|
// as dequeue will get to it eventually
|
||||||
|
if !wstate.Load() {
|
||||||
|
queueSync.Add(1)
|
||||||
|
msgbuf <- op
|
||||||
|
} else {
|
||||||
|
// increment dropped message count
|
||||||
|
dropped.Add(1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
type dOp interface{ Do() }
|
type dOp interface{ Do() }
|
||||||
|
|
||||||
func Exit(code int) {
|
func Exit(code int) {
|
||||||
|
@ -47,6 +67,9 @@ func Resume() {
|
||||||
dequeueOnce.Do(dequeue)
|
dequeueOnce.Do(dequeue)
|
||||||
if wstate.CompareAndSwap(true, false) {
|
if wstate.CompareAndSwap(true, false) {
|
||||||
withhold <- struct{}{}
|
withhold <- struct{}{}
|
||||||
|
if d := dropped.Swap(0); d != 0 {
|
||||||
|
Printf("dropped %d messages during withhold", d)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -16,20 +16,17 @@ func SetPrefix(prefix string) {
|
||||||
|
|
||||||
func Print(v ...any) {
|
func Print(v ...any) {
|
||||||
dequeueOnce.Do(dequeue)
|
dequeueOnce.Do(dequeue)
|
||||||
queueSync.Add(1)
|
queue(dPrint(v))
|
||||||
msgbuf <- dPrint(v)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func Printf(format string, v ...any) {
|
func Printf(format string, v ...any) {
|
||||||
dequeueOnce.Do(dequeue)
|
dequeueOnce.Do(dequeue)
|
||||||
queueSync.Add(1)
|
queue(&dPrintf{format, v})
|
||||||
msgbuf <- &dPrintf{format, v}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func Println(v ...any) {
|
func Println(v ...any) {
|
||||||
dequeueOnce.Do(dequeue)
|
dequeueOnce.Do(dequeue)
|
||||||
queueSync.Add(1)
|
queue(dPrintln(v))
|
||||||
msgbuf <- dPrintln(v)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func Fatal(v ...any) {
|
func Fatal(v ...any) {
|
||||||
|
|
Loading…
Reference in New Issue