Skip to content

Conversation

@sundb
Copy link
Collaborator

@sundb sundb commented Mar 15, 2025

Fix #13853 (review)

This PR ensures that the client's current command is not reset by unblockClient(), while still needing to be handled after unblockclient().
The FLUSH command still requires reprocessing (update the replication offset) after unblockClient(). Therefore, we mark such blocked clients with the CLIENT_PENDING_COMMAND flag to prevent the command from being reset during unblockClient().

@sundb sundb requested a review from oranagra March 15, 2025 14:19

/* FLUSH command is finished. resetClient() and update replication offset. */
commandProcessed(c);
if (c->flags & CLIENT_PENDING_COMMAND) {
Copy link
Member

Choose a reason for hiding this comment

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

this, combined with the check in unblockClient, would mean that resetClient will be performed only once, right?
but maybe the call to resetClient and reqresAppendResponse should be converted to a call for commandProcessed?
on one hand, the command was aborted in that flow, but on the other hand, it was replied, so in that way it was processed.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Do you mean change the resetClient and reqresAppendResponse calls in unblock to call commandProcessed()?
This is a bit strange, if there is no CLIENT_PENDING_COMMAND flag, we will ignore the current execution command.
If calling commandProcessed in unblock is a bit confusing, we don't actually reprocess this command, we don't even do any cleaning up.
Another point is that commandProcessed() is prohibited from being called by a blocked client, and we will have to move if (!(c->flags & CLIENT_PENDING_COMMAND) && c->bstate.btype != BLOCKED_SHUTDOWN) down, not sure if there is a risk.

Copy link
Member

Choose a reason for hiding this comment

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

ok, let's drop it.
i didn't look too much into it. just saw two places doing resetClient + reqresAppendResponse, and thought it's dangerous since we can add / change one, and forget the other.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

If we need to process the previous command after unblock, we should do so as follows:

unblockClient();
if (c->flags & CLIENT_PENDING_COMMAND) {
    c->flags &= ~CLIENT_PENDING_COMMAND;
    .... /* continue process command */
}

elapsedStart(&c->bstate.lazyfreeStartTime);

c->bstate.timeout = 0;
c->flags |= CLIENT_PENDING_COMMAND;
Copy link
Member

Choose a reason for hiding this comment

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

are you saying that we were missing n update of the replication offset? can you describe the flow?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

No, the original flow is fine, I just want to use it to illustrate the following flow that we continue with the previous command, so we can assume that we will continue to process it after unblockclient().

Copy link
Member

Choose a reason for hiding this comment

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

so this is just a cleanup not to to avoid unblockclient reset a command that is still being handled?
and has no actual implications? maybe you can improve the description..

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Added comment for it.

Copy link
Member

Choose a reason for hiding this comment

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

i thin i meant in the PR description 😄

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

i'll change it. 😅

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

updated the top comment.

Copy link
Member

Choose a reason for hiding this comment

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

doesn't it still makes it look like there was a bug with the replication offset?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

😏 i think it's okay this time.

@oranagra
Copy link
Member

LGTM

@sundb sundb merged commit 26dcec4 into redis:unstable Mar 19, 2025
18 checks passed
funny-dog pushed a commit to funny-dog/redis that referenced this pull request Sep 17, 2025
Fix redis#13853 (review)

This PR ensures that the client's current command is not reset by
unblockClient(), while still needing to be handled after `unblockclient()`.
The FLUSH command still requires reprocessing (update the replication
offset) after unblockClient(). Therefore, we mark such blocked clients
with the CLIENT_PENDING_COMMAND flag to prevent the command from being
reset during unblockClient().
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.

2 participants