浏览代码

Wait for `run` goroutine to exit before `Close`

The underlying Loggers Close() function can be called with the the
run() goroutine still writing to the driver. This is causing the
fluentd-golang-logger to panic cause it doesn't defensively check
for the closing of the channel before writing to it.
It relies on the docker daemon to keep the contract of not calling Log()
if Close() has already been called.

Contributions by: James Johnston <james.johnston@thumbtack.com>
                  Nathan Wong <nathanw@thumbtack.com>

Signed-off-by: Anuj Varma <anujvarma@thumbtack.com>
Anuj Varma 4 年之前
父节点
当前提交
cf259eb8a0
共有 1 个文件被更改,包括 4 次插入0 次删除
  1. 4 0
      daemon/logger/ring.go

+ 4 - 0
daemon/logger/ring.go

@@ -19,6 +19,7 @@ type RingLogger struct {
 	l         Logger
 	l         Logger
 	logInfo   Info
 	logInfo   Info
 	closeFlag int32
 	closeFlag int32
+	wg        sync.WaitGroup
 }
 }
 
 
 var _ SizedLogger = &RingLogger{}
 var _ SizedLogger = &RingLogger{}
@@ -42,6 +43,7 @@ func newRingLogger(driver Logger, logInfo Info, maxSize int64) *RingLogger {
 		l:       driver,
 		l:       driver,
 		logInfo: logInfo,
 		logInfo: logInfo,
 	}
 	}
+	l.wg.Add(1)
 	go l.run()
 	go l.run()
 	return l
 	return l
 }
 }
@@ -93,6 +95,7 @@ func (r *RingLogger) setClosed() {
 func (r *RingLogger) Close() error {
 func (r *RingLogger) Close() error {
 	r.setClosed()
 	r.setClosed()
 	r.buffer.Close()
 	r.buffer.Close()
+	r.wg.Wait()
 	// empty out the queue
 	// empty out the queue
 	var logErr bool
 	var logErr bool
 	for _, msg := range r.buffer.Drain() {
 	for _, msg := range r.buffer.Drain() {
@@ -118,6 +121,7 @@ func (r *RingLogger) Close() error {
 // logger.
 // logger.
 // This is run in a goroutine when the RingLogger is created
 // This is run in a goroutine when the RingLogger is created
 func (r *RingLogger) run() {
 func (r *RingLogger) run() {
+	defer r.wg.Done()
 	for {
 	for {
 		if r.closed() {
 		if r.closed() {
 			return
 			return