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

Java: Cluster SCAN request #1737

Merged
merged 32 commits into from
Jul 3, 2024

Conversation

jduo
Copy link
Collaborator

@jduo jduo commented Jun 30, 2024

Issue #, if available:
N/A

Description of changes:
Support cluster SCAN commands.

This is a port of the Python part of #1623 for Java.

API and implementation notes:

  • ClusterScanCursor is an interface end users should work with. It is in a package exposed in the module.
  • NativeClusterScanCursor is an implementation of the above that is in an internal package. It wraps Rust cursor strings.
  • RedisClusterClient intercepts the result from Rust to wrap the cursor string in a NativeClusterScanCursor
  • The caller is responsible for closing ClusterScanCursor. If they don't, it'll get cleaned up at GC-time, but this is non-deterministic.

By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.

@Yury-Fridlyand Yury-Fridlyand added the java issues and fixes related to the java client label Jul 1, 2024
@jduo jduo marked this pull request as ready for review July 2, 2024 00:30
@jduo jduo requested a review from a team as a code owner July 2, 2024 00:30
@jduo jduo force-pushed the java/dev_jduo_cluster_scan branch 3 times, most recently from b695e4a to dbaabe3 Compare July 2, 2024 18:33
avifenesh and others added 21 commits July 2, 2024 15:15
Signed-off-by: Andrew Carbonetto <[email protected]>
Notes:
- ClusterScanCursor is an interface end users should work with. It is in a package exposed in the module.
- NativeClusterScanCursor is an implementation of the above that is in an internal package. It wraps Rust cursor strings.
- RedisClusterClient intercepts the result from Rust to wrap the cursor string in a NativeClusterScanCursor
- The caller is responsible for closing ClusterScanCursor. If they don't, it'll get cleaned up at GC-time, but this is non-deterministic.
Look for the "finished" string
The same hash could potentially be reused.
* Validate that either the initial cursor is used, or an unfinished cursor.
* Test-by-reference for the initial cursor instead of evaluating its string.
* Clean-up unfinished cursors if they get re-used in scan.
* Throw errors if a finished cursor is passed to scan.
- The cursor object manages updating cursor handles and internal state
- It auto-cleans at the end of the data
- The user can also dispose of the cursor early
When using the ScanOptions type, pass native names through to the rust layer when using cluster scans, and enum names when using standalone scans.
Also flushall before each test to avoid flakiness from leftover state
@jduo jduo force-pushed the java/dev_jduo_cluster_scan branch from 998042d to 7948b57 Compare July 2, 2024 22:15
Copy link
Collaborator

@jonathanl-bq jonathanl-bq left a comment

Choose a reason for hiding this comment

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

Signing off on the Rust portion.

java/src/lib.rs Outdated Show resolved Hide resolved
java/src/lib.rs Show resolved Hide resolved
Copy link
Collaborator

@Yury-Fridlyand Yury-Fridlyand left a comment

Choose a reason for hiding this comment

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

Nice!
I didn't review tests yet, but I trust you.

*/
public static void log(
@NonNull Level level, @NonNull String logIdentifier, @NonNull Throwable throwable) {
// TODO: Add the corresponding API to Python and Node.js.
Copy link
Collaborator

Choose a reason for hiding this comment

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

It is better to post such TODO as a GH task

@@ -35,7 +37,11 @@ public <T> Script(T code, Boolean binarySafeOutput) {
/** Drop the linked script from glide-rs <code>code</code>. */
@Override
public void close() throws Exception {
dropScript(hash);

Copy link
Collaborator

Choose a reason for hiding this comment

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

Do we need to synchronise this?

python/python/tests/test_async_client.py Outdated Show resolved Hide resolved
Signed-off-by: Andrew Carbonetto <[email protected]>

@Override
public void releaseCursorHandle() {
// Ignore.
Copy link
Contributor

Choose a reason for hiding this comment

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

It overrides the interface and doesn't destroy the instance object.
That way James has smartly prevented anyone from destroying the statically created INITIAL_CURSOR_INSTANCE.

@acarbonetto acarbonetto merged commit 867cd9b into valkey-io:main Jul 3, 2024
17 checks passed
@acarbonetto acarbonetto deleted the java/dev_jduo_cluster_scan branch July 3, 2024 05:25
cyip10 pushed a commit to Bit-Quill/valkey-glide that referenced this pull request Jul 16, 2024
* Added Scan logic to Glide-core

* added scan to python

* added changes to changelog

* fixed comments

* changed from hash to nanoid

* fixed typing

* fixed comments

* Stubbing for cluster scan

* Update ScanOptions

Signed-off-by: Andrew Carbonetto <[email protected]>

* ClusterScan implementation

Notes:
- ClusterScanCursor is an interface end users should work with. It is in a package exposed in the module.
- NativeClusterScanCursor is an implementation of the above that is in an internal package. It wraps Rust cursor strings.
- RedisClusterClient intercepts the result from Rust to wrap the cursor string in a NativeClusterScanCursor
- The caller is responsible for closing ClusterScanCursor. If they don't, it'll get cleaned up at GC-time, but this is non-deterministic.

* Make cursor termination behave as Python does

Look for the "finished" string

* Unrelated: avoid double-dropping of scripts

The same hash could potentially be reused.

* Better state management of cursors

* Validate that either the initial cursor is used, or an unfinished cursor.
* Test-by-reference for the initial cursor instead of evaluating its string.
* Clean-up unfinished cursors if they get re-used in scan.
* Throw errors if a finished cursor is passed to scan.

* Update design for an iterative cursor

- The cursor object manages updating cursor handles and internal state
- It auto-cleans at the end of the data
- The user can also dispose of the cursor early

* Change the API to match Python

* Unit tests

* Fix integration tests

When using the ScanOptions type, pass native names through to the rust layer when using cluster scans, and enum names when using standalone scans.

* Integration test for cluster scan options

* Spotless

* Add more integration tests

Also flushall before each test to avoid flakiness from leftover state

* Move population of the ScanOptions protobuf to CommandManager

* Rename clusterScan() method to scan()

For consistency with Python

* Add javadoc comments

* Spotless

* Abstract the cursor string from the public API

Move access to this to an internal detail interface.

The user shouldn't need this string themselves.

* Spotless

* Revert accidental changes

resolve conflicts

* Address review comments

* Get protocol string constants from Rust instead of hard-coding them

* Add integration testing for the Stream type filter

* Spotless

* Update scan documentation

Signed-off-by: Andrew Carbonetto <[email protected]>

---------

Signed-off-by: Andrew Carbonetto <[email protected]>
Co-authored-by: avifenesh <[email protected]>
Co-authored-by: Andrew Carbonetto <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
java issues and fixes related to the java client
Projects
Status: No status
Development

Successfully merging this pull request may close these issues.

6 participants