fix logger channel blocking

This commit is contained in:
zelig 2014-07-14 18:37:01 +01:00
parent 4d77b7face
commit 5c03adbded
2 changed files with 49 additions and 33 deletions

@ -39,9 +39,8 @@ func (msg *logMessage) send(logger LogSystem) {
var logMessages chan (*logMessage) var logMessages chan (*logMessage)
var logSystems []LogSystem var logSystems []LogSystem
var quit chan bool var quit chan chan error
var drained chan bool var drained chan bool
var shutdown chan bool
var mutex = sync.Mutex{} var mutex = sync.Mutex{}
type LogLevel uint8 type LogLevel uint8
@ -55,44 +54,54 @@ const (
DebugDetailLevel DebugDetailLevel
) )
// log messages are dispatched to log writers func dispatch(msg *logMessage) {
func start() { for _, logSystem := range logSystems {
out: if logSystem.GetLogLevel() >= msg.LogLevel {
for { msg.send(logSystem)
select {
case <-quit:
break out
case msg := <-logMessages:
for _, logSystem := range logSystems {
if logSystem.GetLogLevel() >= msg.LogLevel {
msg.send(logSystem)
}
}
case drained <- true:
default:
drained <- true // this blocks until a message is sent to the queu
} }
} }
close(shutdown) }
// log messages are dispatched to log writers
func start() {
for {
select {
case status := <-quit:
status <- nil
return
case msg := <-logMessages:
dispatch(msg)
default:
drained <- true // this blocks until a message is sent to the queue
}
}
}
func send(msg *logMessage) {
logMessages <- msg
select {
case <-drained:
default:
}
} }
func Reset() { func Reset() {
mutex.Lock() mutex.Lock()
defer mutex.Unlock() defer mutex.Unlock()
if logSystems != nil { if logSystems != nil {
quit <- true status := make(chan error)
quit <- status
select { select {
case <-drained: case <-drained:
default:
} }
<-shutdown <-status
} }
logSystems = nil logSystems = nil
} }
// waits until log messages are drained (dispatched to log writers) // waits until log messages are drained (dispatched to log writers)
func Flush() { func Flush() {
mutex.Lock()
defer mutex.Unlock()
if logSystems != nil { if logSystems != nil {
<-drained <-drained
} }
@ -110,22 +119,14 @@ func AddLogSystem(logSystem LogSystem) {
mutex.Lock() mutex.Lock()
defer mutex.Unlock() defer mutex.Unlock()
if logSystems == nil { if logSystems == nil {
logMessages = make(chan *logMessage) logMessages = make(chan *logMessage, 5)
quit = make(chan bool) quit = make(chan chan error, 1)
drained = make(chan bool, 1) drained = make(chan bool, 1)
shutdown = make(chan bool, 1)
go start() go start()
} }
logSystems = append(logSystems, logSystem) logSystems = append(logSystems, logSystem)
} }
func send(msg *logMessage) {
select {
case <-drained:
}
logMessages <- msg
}
func (logger *Logger) sendln(level LogLevel, v ...interface{}) { func (logger *Logger) sendln(level LogLevel, v ...interface{}) {
if logSystems != nil { if logSystems != nil {
send(newPrintlnLogMessage(level, logger.tag, v...)) send(newPrintlnLogMessage(level, logger.tag, v...))

@ -28,6 +28,21 @@ func (t *TestLogSystem) GetLogLevel() LogLevel {
return t.level return t.level
} }
func TestLoggerFlush(t *testing.T) {
logger := NewLogger("TEST")
testLogSystem := &TestLogSystem{level: WarnLevel}
AddLogSystem(testLogSystem)
for i := 0; i < 5; i++ {
logger.Errorf(".")
}
Flush()
Reset()
output := testLogSystem.Output
if output != "[TEST] .[TEST] .[TEST] .[TEST] .[TEST] ." {
t.Error("Expected complete logger output '[TEST] .[TEST] .[TEST] .[TEST] .[TEST] .', got ", output)
}
}
func TestLoggerPrintln(t *testing.T) { func TestLoggerPrintln(t *testing.T) {
logger := NewLogger("TEST") logger := NewLogger("TEST")
testLogSystem := &TestLogSystem{level: WarnLevel} testLogSystem := &TestLogSystem{level: WarnLevel}