Skip to content

Potential pathological case where Cache Advance reads no messages for a non-empty file #57

@bachand

Description

@bachand

In reviewing #52 I read this code again:

func nextEncodedMessage(previousReadWasEmpty: Bool = false) throws -> Data? {
let startingOffset = offsetInFile
guard startingOffset != offsetInFileAtEndOfNewestMessage else {
// We're at the last message.
return nil
}

We bail out of reading messages when we encounter the end of start of the newest message.

I'm wondering if there is a pathologic case where we have a file where the offset of the start of the oldest message (reader offset) equals the offset of the end of the newest message (writer offset).

| header | message 4 | message 5 | message 3 | EOF |

Let's image a file like above, with no empty space between messages. If there were no empty space between message 5 and message 3, then when someone invoked message() I believe we would be in a situation where startingOffset == offsetInFileAtEndOfNewestMessage, and we would return no messages. It seems like the current implementation of messages() assumes that there will always be some blank space between the end of the oldest message and the start of the newest message when we're in the situation where the messages have "wrapped around."


In writing this issue I wrote a test to I try to verify if this pathological case is real.

    func test_messagesPathologicalCase() throws {
        let message: TestableMessage = "This is a test"
        let cache = try createCache(sizedToFit: [message, message], overwritesOldMessages: true)
        try cache.append(message: message)
        try cache.append(message: message)
        try cache.append(message: message)

        XCTAssertEqual(try cache.messages().count, 2)
    }

I expected this test to fail saying that the count was 0. However, I received this failure instead:

XCTAssertEqual failed: ("1") is not equal to ("2")

Maybe it's not possible to get into this situation since this code verifies that the writer offset never equals the reader offset.

// And our writer doesn't have enough room to write a message such that it stays behind the current reader position.
&& writer.offsetInFile + messageLength >= reader.offsetInFile

I decided it was still valuable to post this writeup so I can get confirmation from @dfed that this pathological case is not possible.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions