瀏覽代碼

fix a race in json logger reader

The json decoder starts to decode immediately an inotify event is
received.
But at the time the inotify event is trigged, the json log
entry might haven't been fully written to the disk.
In this case the decoder will return an "io.UnexpectedEOF" error, but
there is still data remaining in the decoder's buffer. And the data
should be passed to the decoder when the next inotify event is
triggered.

Signed-off-by: Shijiang Wei <mountkin@gmail.com>
Shijiang Wei 9 年之前
父節點
當前提交
e41eae8b42
共有 1 個文件被更改,包括 11 次插入0 次删除
  1. 11 0
      daemon/logger/jsonfilelog/jsonfilelog.go

+ 11 - 0
daemon/logger/jsonfilelog/jsonfilelog.go

@@ -357,6 +357,17 @@ func followLogs(f *os.File, logWatcher *logger.LogWatcher, notifyRotate chan int
 					retries++
 					retries++
 					continue
 					continue
 				}
 				}
+
+				// io.ErrUnexpectedEOF is returned from json.Decoder when there is
+				// remaining data in the parser's buffer while an io.EOF occurs.
+				// If the json logger writes a partial json log entry to the disk
+				// while at the same time the decoder tries to decode it, the race codition happens.
+				if err == io.ErrUnexpectedEOF && retries <= maxJSONDecodeRetry {
+					reader := io.MultiReader(dec.Buffered(), f)
+					dec = json.NewDecoder(reader)
+					retries++
+					continue
+				}
 				logWatcher.Err <- err
 				logWatcher.Err <- err
 				return
 				return
 			}
 			}