Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: take indices to messages as a hint #5683

Merged
merged 5 commits into from
Nov 2, 2024

Conversation

Nerixyz
Copy link
Contributor

@Nerixyz Nerixyz commented Oct 28, 2024

#2804 shows that using indices across different channels can be buggy. In ChannelView we maintain two buffers - the buffer for the virtual channel and the buffer for the messages. But more importantly, we blindly re-use indices from messageReplaced events from the underlying channel to index into the virtual channel. Both channels don't necessarily have the same messages (e.g. when using filters). Thus, we can't re-use the indices. However, as time shows, in most cases, the index we get will be correct, as most of the time, that index is zero (i.e. no messages have been added since).

This PR adds a "middle-way" to solve this. LimitedQueue can now take a hint to find and replace items. If that hint points to the expected item, no additional work is required. However, if that hint doesn't match, the whole buffer is searched for the desired item.

Fixes #2804 (hopefully, I couldn't replicate it - if this doesn't solve it, we have reentrancy issues when replacing messages)

Copy link
Contributor

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

clang-tidy made some suggestions

tests/src/LimitedQueue.cpp Show resolved Hide resolved
tests/src/LimitedQueue.cpp Show resolved Hide resolved
tests/src/LimitedQueue.cpp Show resolved Hide resolved
tests/src/LimitedQueue.cpp Show resolved Hide resolved
tests/src/LimitedQueue.cpp Show resolved Hide resolved
tests/src/LimitedQueue.cpp Show resolved Hide resolved
tests/src/LimitedQueue.cpp Show resolved Hide resolved
tests/src/LimitedQueue.cpp Show resolved Hide resolved
@hemirt
Copy link
Contributor

hemirt commented Oct 28, 2024

if this doesn't solve it, we have reentrancy issues when replacing messages

By this, do you mean the fact that the circular buffer could have shifted underneath?

That could have also caused this, that was what I had in mind looking at this, and thought of a similar solution to yours (i.e. replace index with the message pointer and check based on that).

Other than that I didnt quite think up any other possible causes.

Of course, supposing this was the problem, I tried forcing replication and still didn't achieve much, though maybe a hardcoded test with this could replicate it.

I think your tests do not test when the buffer is full - it might be something to look at.

@hemirt
Copy link
Contributor

hemirt commented Oct 28, 2024

(a side note) 6430682 ULL suffix should be in c++11, i did not see you use the c++23 z suffix. (If needed there's also the possibility of using custom suffixes - user literals)

(Maybe im just seeing sth wrong in github)

@Nerixyz
Copy link
Contributor Author

Nerixyz commented Oct 29, 2024

By this, do you mean the fact that the circular buffer could have shifted underneath?

Yes. Probably a bit more general than reentrancy, but related in that assumptions about indices are invalidated.

Of course, supposing this was the problem, I tried forcing replication and still didn't achieve much, though maybe a hardcoded test with this could replicate it.

I could test Channel, but I can't test ChannelView (which is where the bug seems to be).

I think your tests do not test when the buffer is full - it might be something to look at.

Sure.

(a side note) 6430682 ULL suffix should be in c++11, i did not see you use the c++23 z suffix. (If needed there's also the possibility of using custom suffixes - user literals)

(Maybe im just seeing sth wrong in github)

ULL isn't portable. On Windows, ULL is equivalent to a size_t, but on other platforms, where sizeof(int) != sizeof(long), UL is equivalent to size_t. Adding a custom suffix for this test would be too much imo (maybe in a refactor).

@hemirt
Copy link
Contributor

hemirt commented Oct 30, 2024

ULL isn't portable. On Windows, ULL is equivalent to a size_t, but on other platforms, where sizeof(int) != sizeof(long), UL is equivalent to size_t. Adding a custom suffix for this test would be too much imo (maybe in a refactor).

Didn't know that there were some things like that with regards to size_t type, granted, unless it is larger than unsigned long long, which the verbiage in standard seems to allow, using ull should be fine to cover possible issues with regards integer conversion and comparison problems.

I didn't know the underlying issue and just saw the commit name and the code, so thought something didnt add up, thanks for the explanation.

But yeah, this isnt really much needed in the tests 👍

@Nerixyz
Copy link
Contributor Author

Nerixyz commented Oct 30, 2024

should be fine to cover possible issues with regards integer conversion and comparison problems.

If you only have an argument of size_t it's usually fine. But if you have it as a template argument, this breaks: https://godbolt.org/z/3vGE389x4.

@pajlada pajlada enabled auto-merge (squash) November 2, 2024 11:45
Copy link
Contributor

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

clang-tidy made some suggestions

return i == 0;
})
.has_value());
EXPECT_EQ(queue
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: unchecked access to optional value [bugprone-unchecked-optional-access]

    EXPECT_EQ(queue
              ^

})
.value(),
1);
EXPECT_EQ(queue
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: unchecked access to optional value [bugprone-unchecked-optional-access]

    EXPECT_EQ(queue
              ^

})
.value(),
2);
EXPECT_EQ(queue
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: unchecked access to optional value [bugprone-unchecked-optional-access]

    EXPECT_EQ(queue
              ^

})
.has_value());
// correct hint
EXPECT_EQ(queue
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: unchecked access to optional value [bugprone-unchecked-optional-access]

    EXPECT_EQ(queue
              ^

})
.value(),
(Pair{0, 1}));
EXPECT_EQ(queue
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: unchecked access to optional value [bugprone-unchecked-optional-access]

    EXPECT_EQ(queue
              ^

.value(),
(Pair{1, 2}));
// incorrect hint
EXPECT_EQ(queue
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: unchecked access to optional value [bugprone-unchecked-optional-access]

    EXPECT_EQ(queue
              ^

})
.value(),
(Pair{0, 1}));
EXPECT_EQ(queue
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: unchecked access to optional value [bugprone-unchecked-optional-access]

    EXPECT_EQ(queue
              ^

.value(),
(Pair{5, 6}));
// oob hint
EXPECT_EQ(queue
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: unchecked access to optional value [bugprone-unchecked-optional-access]

    EXPECT_EQ(queue
              ^

@pajlada pajlada merged commit 5f76f5b into Chatterino:master Nov 2, 2024
18 checks passed
@Nerixyz Nerixyz deleted the fix/hint-index branch November 2, 2024 12:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Message disappeared while someone else banned a user
3 participants