-
-
Notifications
You must be signed in to change notification settings - Fork 1.4k
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
[FIXED] Improve per-subject state performance & keep ss.Last
up-to-date
#6235
Conversation
Signed-off-by: Maurice van Veen <github@mauricevanveen.com>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What was the original code doing here before the changes that we are now deleting?
What was the bug we were trying to fix?
Signed-off-by: Maurice van Veen <github@mauricevanveen.com>
The original bug was here: https://github.com/nats-io/nats-server/pull/6226/files#diff-384c189826934c9a6fc3554dafc63dab2076245010e3d6fce5c71a93e15e9877L7946-L7949 If However, doing that after doing |
ss.Last should always be correct, only ss.First could be wrong.. So this original code would only need to check if firstNeedsUpdate if the seq being deleted is not the last. // Only one left.
if ss.Msgs == 1 {
if seq == ss.Last {
if ss.firstNeedsUpdate {
mb.recalculateFirstForSubj(subj, ss.First, ss)
}
ss.Last = ss.First
} else {
ss.First = ss.Last
ss.firstNeedsUpdate = false
}
} I think the code above would do the trick. |
No, If we delete a message where For example with |
Ah gotcha, when ss.Msgs != 1 and we delete last and ss.Msgs after delete is also != 1. |
Yeah, and turns out we can just defer "recalculating" |
Do we need ss.Last to be correct for looking up ast by subject or do we use PSIM? What happens when we asked for SubjectState? If this is wrong does it effect that? |
Turns out yes. But that's as simple as just deleting the last message, and then doing a lookup of the last message for that subject for it to not work anymore. So we'll also need to mark |
Signed-off-by: Maurice van Veen <github@mauricevanveen.com>
Have added a fix to this PR 🙂 |
ss.Last
up-to-date
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Question, could we just hook RemoveMsg() and check once we have the block if the seq matches first or last and if so re-calculate there? Unless ss.Msgs now equals 1 and if we always keep them updated that should be a simple assignment?
Functionally that would work but performance-wise I think it would regress just like when I added the recalc earlier in #6226. |
The majority of use cases will be expiring the first and removing it. For WQs and interest streams they can be removed out of order yes. |
Have tried this out by removing So I'd say (at least for now) we need to keep |
Will experiment some more, have a hunch where we could improve to possibly not regress. I'll report back later. |
Conclusion; it's not easy to make Making them always be consistent means we can remove But.. quickly that strategy falls down. It quickly snowballs and would end up requiring more code and "spaghetti" to be able to influence from a high level whether Would propose to leave the logic of having @derekcollison , would it be okay to merge this PR first, to fix the performance regression and bug on |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
Improve performance by only setting
ss.Last
during recalculation, so only when it's needed.Also fixes a bug where
ss.Last
was not kept up-to-date ifss.Msgs > 1
, by introducing ass.lastNeedsUpdate
just likess.firstNeedsUpdate
.Signed-off-by: Maurice van Veen github@mauricevanveen.com