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

ZMPOP and LMPOP #2094

Merged
merged 30 commits into from
Apr 19, 2022
Merged

ZMPOP and LMPOP #2094

merged 30 commits into from
Apr 19, 2022

Conversation

slorello89
Copy link
Collaborator

Implementing ZMPOP and LMPOP as part of #2055

Copy link
Collaborator

@NickCraver NickCraver left a comment

Choose a reason for hiding this comment

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

Going to ask @mgravell for some time here too, but looking a this current API thoughts:

  • I think the return types make sense, but would prefer not-nullable, this is a regret with existing I found inconsistent in doing NRTs. For example a ListSpan.Null (which would need the RedisKey.Null from your other PR) instead of nullable.
    • Same for SortedSetSpan
    • ...but we shouldn't call them that, I don't think. Span is a very core term in .NET now and these aren't related really. Maybe ListValues? SortedSetValues? The latter is weird because it's score plus value, but anyway I think we should find an alternative name for these types. SortedSetEntries? Spitballing here.
    • A ton of line formatting changes landed in RedisDatabase.cs, can you revert those please?
    • Docs need a tidy but I'm happy to do that normalization pass/cleanup

Thoughts on the above? There's definitely a pending message question w.r.t. cluster handling and key hashing we need to revisit on several recent PRs that I don't think I caught. Let's do a full pass there but address in this one as a baseline.

args[i++] = count;
}

return Message.Create(Database, flags, RedisCommand.LMPOP, args);
Copy link
Collaborator

Choose a reason for hiding this comment

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

After looking at the recent issues, I'm not sure how this behaves in cluster. Can you pop across multiple servers? If not, how does it behave? This message overload will not calculate the hash correctly for any keys, so I think we're lacking a proper message type here. /cc @mgravell

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Almost certainly not, this will probably break horribly if the keys don't happen to lie on the same shard as the multiplexer hits, curiously there's another multi-key command that I used this pattern from that likely has the same problem, as you said maybe let's categorize these, I'll write the prototype here, and then after this is merged I'll import that pattern elsewhere?

src/StackExchange.Redis/ResultProcessor.cs Show resolved Hide resolved
src/StackExchange.Redis/ResultProcessor.cs Outdated Show resolved Hide resolved
src/StackExchange.Redis/ResultProcessor.cs Show resolved Hide resolved
src/StackExchange.Redis/SortedSetSpan.cs Outdated Show resolved Hide resolved
src/StackExchange.Redis/SortedSetSpan.cs Outdated Show resolved Hide resolved
src/StackExchange.Redis/StackExchange.Redis.csproj Outdated Show resolved Hide resolved
src/StackExchange.Redis/Interfaces/IDatabaseAsync.cs Outdated Show resolved Hide resolved
@slorello89
Copy link
Collaborator Author

slorello89 commented Apr 15, 2022

@NickCraver - apologies for the formatting changes in RedisDatabase, Rider apparently had some opinions and I didn't catch it when I was pushing it, I'll clean it up

  • RE naming, yeah names are tough to come up for these, I was considering using RedisList and RedisSortedSet because the precedent was already there for RedisStream which does something similar, but I didn't want to reserve those class names, hence the use of ListSpan and SortedSetSpan as they are contiguous regions of lists/sorted sets (the name was an intentional homage to that). Maybe SubList and SortedSubSet?

  • I can work up some derived Null value

  • RE Cluster - I had similar questions, given the questions RE streams that have come up in the last couple days, I can spin up a cluster and check, but I'd guess that it will either throw up if all the keys aren't on the node, or if it comes across a key as it's scanning through this list of keys, either way, it shouldn't be operating across shards. There doesn't appear to be a message that takes an array of keys and an array of values, so maybe we need a new message CommandValueKeysValuesMessage? I'll work up some Cluster test-cases for this as well

@slorello89
Copy link
Collaborator Author

@NickCraver - this looks promising?

@slorello89
Copy link
Collaborator Author

@NickCraver - just pushed a change to take advantage of the slot-specified Message type, I'll look into adding some proper cluster tests for it next week. I think there's a philosophical question, do you want to pre-flight validate that all the keys are in the same slot? Or just make our best effort to point it at the right slot and let the rejection be Redis's problem?

@NickCraver
Copy link
Collaborator

I dunno - @mgravell is working on connection shenanigans and probably has better input here - note I'm out next week but I'll try and keep a few things moving as around on a laptop. I had to get a lot in queue wrapped up at work today so didn't get to peruse PRs much here.

@NickCraver
Copy link
Collaborator

Okay I played with this...still not digging the naming, we're inconsistent e.g. ListEntries.Values and SortedSetEntries.Entries but...I don't think any combination of that is awesome. Thoughts on ListPopResult.Values, SortedSetPopResult.Entries? This would match our general terminology and the single results now (e.g. RedisResult/SortedSetEntry).

I'm happy to hack at the change, just looking for feedback before more code shenanigans :)

@slorello89
Copy link
Collaborator Author

@NickCraver, I'm good with those names, discrete enough to what they're being used for I suppose, I can make the change.

slorello89 and others added 4 commits April 15, 2022 21:25
In the RedisValue case this isn't needed because of implicit operators, but we may have a null array here with a default, so explicitly use the defaults.
/// Removes and returns at most specified <paramref name="count"/> of elements from the first non-empty list
/// within the set of <paramref name="keys"/> passed into it.
/// Starts on the left side of the list.
/// If the length of the first non-empty list is less than <paramref name="count"/>, only the elements within that list are returned.
Copy link
Collaborator

@NickCraver NickCraver Apr 16, 2022

Choose a reason for hiding this comment

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

@slorello89 Does this matter? e.g. is it equally correct and maybe clearer to simplify to:

Only the elements from the first non-empty list are ever returned, even if <paramref name="count"/> is higher than its length.

...or is that more confusing and/or plain wrong?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

The important point is that the first list it encounters is what it pops elements out of. Both ways of phrasing it get at that point so whichever is simpler.

Copy link
Collaborator

Choose a reason for hiding this comment

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

kk - to me it's confusing currently - will adjust, can always change again!

Copy link
Collaborator

@NickCraver NickCraver left a comment

Choose a reason for hiding this comment

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

I think current looks good, but I also touched this a lot. @mgravell, @Avital-Fine could one of you lend eyes on latest here please?

@slorello89
Copy link
Collaborator Author

@NickCraver - do you feel like the issues surrounding key-slot mappings have been sufficiently addressed?

@NickCraver
Copy link
Collaborator

I think we're good, but would like to holistically visit adding some tests targeting cluster for several of these APIs before releasing 2.6. I'm mobile at the moment but was going to create an issue there to track so we remember.

Matching this to #2095 and I'll move others here separately.
I realized we have many inputs too doing #2096
NickCraver added a commit that referenced this pull request Apr 19, 2022
@NickCraver, working on `BITFIELD`/`BITFIELD_RO` and I realized that several of the new commands we've been adding are write-commands and therefore won't work on replicas, opening this to fix the command-map in Message.cs (pretty sure this is the right place but LMK if I'm offbase here) will need to push an update to #2095 #2094 to reflect this as well.

Co-authored-by: Nick Craver <nrcraver@gmail.com>
@NickCraver NickCraver merged commit dbd52f1 into main Apr 19, 2022
@NickCraver NickCraver deleted the feature/ZMPOP branch April 19, 2022 16:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants