Skip to content

fix: Remove unnecessary Task<bool> return types from GLIDE-native methods#261

Merged
currantw merged 11 commits intovalkey-io:mainfrom
currantw:currantw/remove-unnecessary-bool-return-types
Apr 3, 2026
Merged

fix: Remove unnecessary Task<bool> return types from GLIDE-native methods#261
currantw merged 11 commits intovalkey-io:mainfrom
currantw:currantw/remove-unnecessary-bool-return-types

Conversation

@currantw
Copy link
Copy Markdown
Collaborator

@currantw currantw commented Apr 2, 2026

Summary

Remove misleading Task return types from four GLIDE-native methods where the boolean was always true. The underlying Valkey commands (RENAME, unconditional SET, XGROUP CREATE, XGROUP SETID) always return OK or throw — they never return false. Changed these methods to return Task (void) at the GLIDE-native layer, while SER-compatible wrappers in Database continue to return Task for StackExchange.Redis API compatibility.

This continues the return type cleanup started in #230, which replaced "OK" string returns with void. This PR addresses the remaining cases where Task` was used for commands that always succeed or throw.

Also adds two new StringSetAsync convenience overloads.

Issue Link

⚪ None.

Features and Behaviour Changes

Return type changes for Valkey GLIDE interface:

  • KeyRenameAsync(ValkeyKey, ValkeyKey): TaskTask
  • StringSetAsync(ValkeyKey, ValkeyValue): TaskTask
  • StreamCreateConsumerGroupAsync (both overloads): TaskTask
  • StreamConsumerGroupSetPositionAsync: TaskTask

New StringSetAsync overloads:

  • Task StringSetAsync(IEnumerable> values)
  • Task StringSetAsync(ValkeyKey key, ValkeyValue value, When when)

Default parameter removal:

  • Removed When.Always default from StringSetAsync(IEnumerable> values, When when) to prevent ambiguity between unconditional (Task) and conditional (Task) overloads

Exception type fix for multi-key StringSetAsync with unsupported When values:

  • Changed When.Exists to throw ArgumentException instead of NotImplementedException, matching StackExchange.Redis behavior (SER throws ArgumentException via its internal WhenAlwaysOrNotExists guard)
  • Changed the catch-all default arm to also throw ArgumentException (was ArgumentOutOfRangeException)
  • Updated XML docs on IStringCommands to document supported When values and the ArgumentException
  • Added TODO #262 comments for future refactor into separate StringSetNXAsync method

Implementation

Valkey GLIDE interface (Commands/I*Commands.cs, BaseClient.*Commands.cs):

  • Changed return types from Task to Task for the four affected methods
  • BaseClient implementations discard the bool result using _ = await Command(...)
  • Added Request.StringSetNX and Request.StringSetXX for SET NX/SET XX support in the new conditional single-key overload

StackExchange.Redis interface (Abstract/Database.*Commands.cs):

  • Wrappers await the base GLIDE-native void methods and return true, preserving Task for StackExchange.Redis compatibility
  • Fixed recursive overload resolution in Database.StreamCommands.cs by casting to ((BaseClient)this) to ensure dispatch to the correct base methods instead of the Database overloads with default parameters

StackExchange.Redis compatibility:

  • All SER-compatible overloads (with CommandFlags parameter) in IDatabaseAsync and Database retain their Task return types
  • Methods with meaningful boolean semantics are unchanged: KeyRenameNXAsync, StringSetAsync with When.NotExists/When.Exists, StreamDeleteConsumerGroupAsync, StreamCreateConsumerAsync
  • The SER interface files (IDatabaseAsync.*Commands.cs) required no changes

Limitations

⚪ None

Testing

Unit tests:

  • Added Request.StringSetNX/StringSetXX argument builder and converter tests in CommandTests.cs
  • All 501 unit tests pass

Integration tests:

  • Updated 17 integration test files to use void return where applicable
  • Added conditional single-key StringSetAsync(key, value, When) integration tests covering When.NotExists, When.Exists, and When.Always branches

Related Issues

Checklist

  • This Pull Request is related to one issue.
  • Commit message has a detailed description of what changed and why.
  • Tests are added or updated and all checks pass.
  • CHANGELOG.md, README.md, DEVELOPER.md, and other documentation files are updated.
  • Destination branch is correct - main or release
  • Create merge commit if merging release branch into main, squash otherwise.

currantw added 8 commits April 2, 2026 08:23
The RENAME command always returns OK or throws — the bool was always true
and conveyed no useful information. Change the GLIDE-native interface and
BaseClient implementation to return Task (void). The SER-compatible
Database wrapper continues to return Task<bool> for StackExchange.Redis
API compatibility.

Signed-off-by: currantw <taylor.curran@improving.com>
…and add new overloads

- Change single-key StringSetAsync(key, value) from Task<bool> to Task
- Add unconditional multi-key overload StringSetAsync(values) returning Task
- Remove default When.Always from existing multi-key conditional overload
- Add conditional single-key overload StringSetAsync(key, value, When)
- Add Request.StringSetNX and Request.StringSetXX for SET NX/XX support
- SER-compatible Database wrappers continue to return Task<bool>

Signed-off-by: currantw <taylor.curran@improving.com>
…erGroupSetPositionAsync to Task

Both XGROUP CREATE and XGROUP SETID always return OK or throw — the bool
was always true. Change the GLIDE-native interface and BaseClient
implementations to return Task (void). SER-compatible Database wrappers
continue to return Task<bool> for StackExchange.Redis API compatibility.

Signed-off-by: currantw <taylor.curran@improving.com>
- Add ReturnTypeTests verifying GLIDE-native methods return Task (void)
- Add ReturnTypeTests verifying SER-compatible methods retain Task<bool>
- Add ReturnTypeTests for new StringSetAsync overloads and When parameter
- Add preservation tests for KeyRenameNXAsync, StreamDeleteConsumerGroupAsync,
  and StreamCreateConsumerAsync (unchanged Task<bool> methods)
- Add Request.StringSetNX/XX argument and converter tests in CommandTests

Signed-off-by: currantw <taylor.curran@improving.com>
- Update StringSetAsync calls to use void return where applicable
- Update StreamCreateConsumerGroupAsync and StreamConsumerGroupSetPositionAsync
  calls to use void return
- Add conditional single-key StringSetAsync(key, value, When) integration tests
- Update all test files that called affected methods with bool assertions

Signed-off-by: currantw <taylor.curran@improving.com>
…wrappers

StreamCreateConsumerGroupAsync and StreamConsumerGroupSetPositionAsync SER
wrappers in Database were resolving to their own overloads (with default
parameters) instead of the BaseClient methods, causing infinite recursion.
Cast to BaseClient explicitly to ensure correct dispatch to the void-returning
GLIDE-native methods.

Signed-off-by: currantw <taylor.curran@improving.com>
Remove reflection-based return type verification tests. The return type
contracts are already enforced by the compiler at integration test call
sites and by the interface definitions themselves.

Signed-off-by: currantw <taylor.curran@improving.com>
…gle-key StringSetAsync

Add tests for the When.Always branch of the new StringSetAsync(key, value, When)
overload, covering both key-exists and key-does-not-exist scenarios.

Signed-off-by: currantw <taylor.curran@improving.com>
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR cleans up async return types for several Valkey GLIDE “always succeeds or throws” commands by removing misleading Task<bool> results at the command-interface/client layers, adding conditional SET support (NX/XX) for single-key sets, and updating tests/call-sites accordingly.

Changes:

  • Updated GLIDE-native command interfaces and BaseClient implementations to return Task (void) for commands that only return OK or throw.
  • Added request builders for SET NX / SET XX and introduced a new conditional single-key StringSetAsync(key, value, When) overload.
  • Updated unit/integration tests and StackExchange-facing wrappers/call-sites to align with new return types and overload resolution.

Reviewed changes

Copilot reviewed 28 out of 28 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
tests/Valkey.Glide.UnitTests/CommandTests.cs Adds unit coverage for Request.StringSetNX/StringSetXX args + converters.
tests/Valkey.Glide.IntegrationTests/StringCommandTests.cs Updates unconditional StringSetAsync usage to void; adds integration tests for When single-key set branches.
tests/Valkey.Glide.IntegrationTests/StreamConsumerGroupTests.cs Updates stream consumer group create/set-position calls to void-returning APIs.
tests/Valkey.Glide.IntegrationTests/StreamCommandTests.cs Updates stream group creation calls to void-returning API.
tests/Valkey.Glide.IntegrationTests/StandaloneClientTests.cs Adjusts set usage to void-returning StringSetAsync.
tests/Valkey.Glide.IntegrationTests/StackExchange/ValkeyServerTests.cs Updates StackExchange-facing tests to not expect boolean from unconditional StringSetAsync.
tests/Valkey.Glide.IntegrationTests/SharedBatchTests.cs Updates setup writes to use void-returning StringSetAsync.
tests/Valkey.Glide.IntegrationTests/ScriptingCommandTests.cs Updates script test setup writes to use void-returning StringSetAsync.
tests/Valkey.Glide.IntegrationTests/ScanTests.cs Updates scan test setup writes to use void-returning StringSetAsync.
tests/Valkey.Glide.IntegrationTests/ReadFromTests.cs Updates read-from tests to use void-returning StringSetAsync.
tests/Valkey.Glide.IntegrationTests/OpenTelemetryTests.cs Updates telemetry test writes to use void-returning StringSetAsync.
tests/Valkey.Glide.IntegrationTests/GeospatialCommandTests.cs Updates wrong-type setup writes to use void-returning StringSetAsync.
tests/Valkey.Glide.IntegrationTests/GenericCommandTests.cs Updates rename/set usage to match void-returning KeyRenameAsync and StringSetAsync.
tests/Valkey.Glide.IntegrationTests/FlushDatabaseTests.cs Updates flush tests setup writes to use void-returning StringSetAsync.
tests/Valkey.Glide.IntegrationTests/DBTests.cs Updates DB smoke test to use void-returning StringSetAsync.
tests/Valkey.Glide.IntegrationTests/ClusterClientTests.cs Updates cluster tests setup writes to use void-returning StringSetAsync.
tests/Valkey.Glide.IntegrationTests/BitmapCommandTests.cs Updates bitmap tests setup writes to use void-returning StringSetAsync.
tests/Valkey.Glide.IntegrationTests/BatchTests.cs Updates batch/transaction tests to treat StringSetAsync as void-returning when called without flags.
sources/Valkey.Glide/Internals/Request.String.cs Adds Request.StringSetNX and Request.StringSetXX builders handling nullable responses.
sources/Valkey.Glide/Commands/IStringCommands.cs Changes unconditional StringSetAsync/multi-set to Task; adds conditional single-key overload and removes default When on multi-set conditional overload.
sources/Valkey.Glide/Commands/IStreamCommands.cs Changes consumer group create/set-position return types to Task (void).
sources/Valkey.Glide/Commands/IGenericBaseCommands.cs Changes KeyRenameAsync return type to Task (void).
sources/Valkey.Glide/BaseClient.StringCommands.cs Implements new void-returning set overloads and When-based single-key conditional set.
sources/Valkey.Glide/BaseClient.StreamCommands.cs Updates consumer group create/set-position implementations to void-returning behavior.
sources/Valkey.Glide/BaseClient.GenericCommands.cs Updates KeyRenameAsync implementation to void-returning behavior.
sources/Valkey.Glide/Abstract/Database.StringCommands.cs Preserves a Task<bool> StackExchange-facing overload by awaiting void set and returning true.
sources/Valkey.Glide/Abstract/Database.StreamCommands.cs Preserves Task<bool> StackExchange-facing overloads and fixes overload recursion via ((BaseClient)this) dispatch.
sources/Valkey.Glide/Abstract/Database.GenericCommands.cs Preserves a Task<bool> StackExchange-facing overload by awaiting void rename and returning true.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread sources/Valkey.Glide/Commands/IStringCommands.cs
Comment thread sources/Valkey.Glide/Commands/IStringCommands.cs Outdated
Comment thread sources/Valkey.Glide/Commands/IGenericBaseCommands.cs
Comment thread sources/Valkey.Glide/Commands/IStreamCommands.cs
Comment thread sources/Valkey.Glide/Commands/IStreamCommands.cs
… into currantw/remove-unnecessary-bool-return-types
…ulti-key StringSetAsync

Change multi-key StringSetAsync to throw ArgumentException (instead of
NotImplementedException) for unsupported When values, matching
StackExchange.Redis behavior. Document supported When values and add
TODO valkey-io#262 comments for future refactor into separate StringSetNXAsync
method.

Addresses review comment on PR valkey-io#261.

Signed-off-by: currantw <taylor.curran@improving.com>
Mark methods in shared I*Commands interfaces that need to move to
IClient.* partials once the GLIDE/SER API surface separation is
implemented. Also mark IDatabaseAsync inheritance declaration.

Signed-off-by: currantw <taylor.curran@improving.com>
@currantw currantw merged commit 8b62a4d into valkey-io:main Apr 3, 2026
21 of 22 checks passed
@currantw currantw deleted the currantw/remove-unnecessary-bool-return-types branch April 3, 2026 01:23
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.

4 participants