Skip to content

Conversation

@enjoy-binbin
Copy link
Contributor

@enjoy-binbin enjoy-binbin commented Jun 16, 2023

In #12301, we observed that if the
while(listLength(server.ready_keys) != 0)
in handleClientsBlockedOnKeys is changed to
if(listLength(server.ready_keys) != 0),
the order of command execution will change.

It is wrong to change that. It means that if a command
being unblocked causes another command to get unblocked
(like a BLMOVE would do), then the new unblocked command
will wait for later to get processed rather than right away.

It'll not have any real implication if we change that since
we do call handleClientsBlockedOnKeys in beforeSleep again,
and redis will still behave correctly, but we don't change that.

An example:

  1. $rd1 blmove src{t} dst{t} left right 0
  2. $rd2 blmove dst{t} src{t} right left 0
  3. $rd3 set key1{t}, $rd3 lpush src{t}, $rd3 set key2{t} in a pipeline

The correct order would be:

  1. set key1{t}
  2. lpush src{t}
  3. lmove src{t} dst{t} left right
  4. lmove dst{t} src{t} right left
  5. set key2{t}

The wrong order would be:

  1. set key1{t}
  2. lpush src{t}
  3. lmove src{t} dst{t} left right
  4. set key2{t}
  5. lmove dst{t} src{t} right left

This PR adds corresponding test to cover it.

@enjoy-binbin enjoy-binbin requested a review from oranagra June 16, 2023 10:06
…ecution order test

In redis#12301, we observed that if the
`while(listLength(server.ready_keys) != 0)`
in handleClientsBlockedOnKeys is changed to
`if(listLength(server.ready_keys) != 0)`,
the order of command execution will change.

It is wrong to change that. It means that if a command
being unblocked causes another command to get unblocked
(like a BLMOVE would do), then the new unblocked command
will wait for later to get processed rather than right away.

It'll not have any real implication if we change that since
we do call handleClientsBlockedOnKeys in beforeSleep again,
and redis will still behave correctly, but we don't change that.

An example:
1. $rd1 blmove src{t} dst{t} left right 0
2. $rd2 blmove dst{t} src{t} right left 0
3. $rd3 set key1{t}, $rd3 lpush src{t}, $rd3 set key2{t} in a pipeline

The correct order would be:
1. set key1{t}
2. lpush src{t}
3. lmove src{t} dst{t} left right
4. lmove dst{t} src{t} right left
5. set key2{t}

The wrong order would be:
1. set key1{t}
2. lpush src{t}
3. lmove src{t} dst{t} left right
4. set key2{t}
5. lmove dst{t} src{t} right left

This PR adds corresponding test to cover it.
Copy link
Member

@oranagra oranagra left a comment

Choose a reason for hiding this comment

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

i now realize that we can also easily write a test that will really get the wrong command result (not just based on order of things in the replication stream).
i.e. if the command after the pipeline would access the src key, it'll get a different result depending on whether the second BLMOVE runs first or not.
but anyway, that test is certainly sufficient to detect the bug next time it happens.

@oranagra oranagra merged commit 9dc6f93 into redis:unstable Jun 16, 2023
@enjoy-binbin enjoy-binbin deleted the add_edge_test branch June 16, 2023 13:00
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