Browse code

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 authored on 2015/10/31 03:15:49
Showing 1 changed files
... ...
@@ -357,6 +357,17 @@ func followLogs(f *os.File, logWatcher *logger.LogWatcher, notifyRotate chan int
357 357
 					retries++
358 358
 					continue
359 359
 				}
360
+
361
+				// io.ErrUnexpectedEOF is returned from json.Decoder when there is
362
+				// remaining data in the parser's buffer while an io.EOF occurs.
363
+				// If the json logger writes a partial json log entry to the disk
364
+				// while at the same time the decoder tries to decode it, the race codition happens.
365
+				if err == io.ErrUnexpectedEOF && retries <= maxJSONDecodeRetry {
366
+					reader := io.MultiReader(dec.Buffered(), f)
367
+					dec = json.NewDecoder(reader)
368
+					retries++
369
+					continue
370
+				}
360 371
 				logWatcher.Err <- err
361 372
 				return
362 373
 			}