Consistent EOF error happens if the reading position is keeping up with the writing position and if the write rolls a file, then read will throw an EOF error since it missed its chance to roll.
It is to do with how the reader rolls, it checks after it has read a message if it should roll to the next file and when it checks it uses a variable that is called maxBytesPerFileRead. The variable is either the files size if the file is complete or the maxBytesPerFile which is configured (e.g 100 MB).
Say readFileNum = d.writeFileNum and maxBytesPerFile = 100 MB
Say we read Msg-1 and after which the nextReadPos is at 96 MB, this is under maxBytesPerFile (100 MB) so we don’t roll.
Then say we write Msg-2 which is 10 MB. It doesn’t fit so we roll the write file and write the message in the new file. Then we set maxBytesPerFileRead = 96 MB
Now when we read we get an EOF error as there is no more data in the file and we missed our chance to roll when we read Msg-1.
Because we hit an EOF we will mark the file as bad and roll to the next file, so we are not missing any messages but we accumulate a lot of unnecessary bad files.
This problem however doesn’t present itself if the reader is more than a message behind the writer, because after the writer has rolled there are still messages in the previous file for the reader to read. He will then be able to use the updated maxBytesPerFileRead value when reading those messages.
A fix is to move the check for roll at the start of the readOne function and roll before we read if necessary.
Flowchart below hopefully helps with the text above.
Consistent EOF error happens if the reading position is keeping up with the writing position and if the write rolls a file, then read will throw an EOF error since it missed its chance to roll.
It is to do with how the reader rolls, it checks after it has read a message if it should roll to the next file and when it checks it uses a variable that is called
maxBytesPerFileRead
. The variable is either the files size if the file is complete or themaxBytesPerFile
which is configured (e.g 100 MB).Say
readFileNum = d.writeFileNum
andmaxBytesPerFile = 100 MB
Say we read Msg-1 and after which thenextReadPos
is at 96 MB, this is undermaxBytesPerFile (100 MB)
so we don’t roll. Then say we write Msg-2 which is 10 MB. It doesn’t fit so we roll the write file and write the message in the new file. Then we setmaxBytesPerFileRead = 96 MB
Now when we read we get an EOF error as there is no more data in the file and we missed our chance to roll when we read Msg-1.Because we hit an EOF we will mark the file as bad and roll to the next file, so we are not missing any messages but we accumulate a lot of unnecessary bad files.
This problem however doesn’t present itself if the reader is more than a message behind the writer, because after the writer has rolled there are still messages in the previous file for the reader to read. He will then be able to use the updated
maxBytesPerFileRead
value when reading those messages.A fix is to move the check for roll at the start of the
readOne
function and roll before we read if necessary.Flowchart below hopefully helps with the text above.![image](https://github.com/nsqio/go-diskqueue/assets/23697986/9eed35e6-241a-4433-96d8-c65337d65f01)