Skip to content

DOC-7267 Give NRedisStack async entries their Async method names and Task returns - #4482

Merged
andy-stark-redis merged 1 commit into
mainfrom
DOC-7267-nredisstack-async
Nov 6, 2026
Merged

andy-stark-redis merged 1 commit into
mainfrom
DOC-7267-nredisstack-async

Conversation

@andy-stark-redis

@andy-stark-redis andy-stark-redis commented Nov 5, 2026 •

Copy link
Copy Markdown
Contributor

Summary

DOC-7267 item 5. 383 core-command entries in nredisstack_async were exact copies of the sync entry, so the Async tab showed StringAppend returning long instead of StringAppendAsync returning Task<long>. Each now has the ...Async name and the real return type from the released interfaces.

The diff is 383 entries changing signature and returns.type, plus the regenerated data/command-api-mapping.json. Parameters and descriptions are unchanged because the async methods take the same parameters. No other client or field changed.

How to review

  • A reflection probe over IDatabaseAsync, IServer, ISubscriber, IRedisAsync and IConnectionMultiplexer found every rewritten entry's method by name, parameter names and parameter types, on StackExchange.Redis 3.3.1 and 3.4.31 with identical results. All 383 resolve on IDatabaseAsync.
  • The apply script only touched entries that were identical to a sync entry and had an exact match, and it refused files that don't round-trip through json.dumps(indent=2).
  • The merged file equals the per-command data, and its only semantic change is those 383 entries.
  • Return types: 380 are Task<T> or Task. Three (HSCAN, SSCAN, ZSCAN, the 6-parameter overload) return IAsyncEnumerable<T> directly, which is what the interface declares.
  • Format: no return prefix in signature, Task<T> in returns.type. That matches the sync core entries and 54 of the existing core async entries. 67 existing core async entries carry a prefix (Task SaveAsync(...)); I left them alone.

Left for the rest of DOC-7267

18 of the 401 copies are not rewritten because the data itself is wrong, not only the copy:

  • 11 sync entries across GET, HINCRBYFLOAT, INCR, INCRBY, INCRBYFLOAT, ZINCRBY and ZREM are expression text such as StringIncrement(key, -value, flags) with a return type of return.
  • GETRANGE and SUBSTR carry a sorted-set helper signature (GetRange(double value, Exclude exclude, bool isStart)).
  • HSCAN, SSCAN and ZSCAN index 0 are 4-parameter overloads with no async twin (index 1 is the real one).
  • KEYS lacks the database parameter that IServer.KeysAsync takes, and SCAN has no ScanAsync.

Separately, 31 commands have an nredisstack_sync entry but no nredisstack_async key at all: 23 JSON.* commands, BLMPOP, BLPOP, BRPOP, BRPOPLPUSH, BZMPOP, BZPOPMAX, BZPOPMIN and SHUTDOWN. The DOC-7263 sweep looked only at empty lists, so it did not see them.

🤖 Generated with Claude Code


Note

Low Risk
Documentation-only metadata in JSON mapping files; no runtime or Redis behavior changes.

Overview
Fixes 383 nredisstack_async entries in per-command mapping JSON that had been duplicated from sync: method signatures now use the real …Async names (e.g. StringGetAsync, HashSetAsync) and return types use Task<T>, Task, or IAsyncEnumerable<T> where the StackExchange.Redis async interfaces do (notably HashScanAsync → IAsyncEnumerable<HashEntry>).

Only the async client slice changes; parameters, descriptions, sync mappings, and other languages are untouched. The merged command-api-mapping.json is regenerated from these files so docs/async tabs show callable async APIs instead of sync-looking names.

Reviewed by Cursor Bugbot for commit b1cb176. Bugbot is set up for automated code reviews on this repo. Configure here.

…Task returns

383 core-command entries in nredisstack_async were exact copies of the sync entry, so the
Async tab showed StringAppend returning long instead of StringAppendAsync returning
Task<long>. Each is rewritten from the released StackExchange.Redis interfaces: the name
gains Async, and returns.type becomes the real return (Task<T>, Task, or IAsyncEnumerable<T>
for the three scan overloads that return it directly). Parameters and descriptions are
untouched because the async methods take the same parameters.

A reflection probe over IDatabaseAsync, IServer, ISubscriber, IRedisAsync and
IConnectionMultiplexer found every rewritten entry's method by name, parameter names and
parameter types, on both 3.3.1 and 3.4.31 with identical results. The apply script only
touched entries that were identical to a sync entry and had an exact match, and the diff
is 383 entries changing signature and returns.type, nothing else.

18 of the 401 copies were left alone because the data, not just the copy, is wrong: 11
sync entries across seven commands are expression text such as StringIncrement(key, -value, flags) with a return
type of "return", GETRANGE and SUBSTR carry a sorted-set helper signature, HSCAN, SSCAN and
ZSCAN index 0 are 4-parameter overloads with no async twin, KEYS lacks the database
parameter that IServer.KeysAsync takes, and SCAN has no ScanAsync. Fixing them needs a
decision per entry, so they stay on DOC-7267.

Learned: a sync copy in the async list can hide broken sync entries, so match each rewrite against the interface before trusting the copy
Constraint: only rewrite an async entry that is identical to a sync entry and has an exact reflection match on name, parameter names and types
Directive: do not rename the 67 core async entries that carry a return-type prefix in signature, that is a separate convention decision
Gaps: signatures were matched by reflection, not compiled, and descriptions were not re-read against the 3.4 XML docs
Ticket: DOC-7267
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
@github-actions

github-actions Bot commented Nov 5, 2026 •

Copy link
Copy Markdown
Contributor

DOC-7267

@github-actions

github-actions Bot commented Nov 5, 2026

Copy link
Copy Markdown
Contributor

🧠 Redis Memory

Found 5 related items from repository history (5 new this commit):

Memory updated at b1cb176

@andy-stark-redis
andy-stark-redis merged commit d92cfb4 into main Nov 6, 2026
211 of 212 checks passed
@andy-stark-redis
andy-stark-redis deleted the DOC-7267-nredisstack-async branch November 6, 2026 10:44
andy-stark-redis added a commit that referenced this pull request Nov 6, 2026
…lient-quirks

The DOC-7267 cleanup PRs (#4482, #4484, #4486) left their durable findings only in commit
bodies, where a future sweep would not see them before authoring. They now sit in the
per-client sections of the command-api-mapping skill's quirks reference: node-redis lists every
command under an uppercase and a camelCase key and modules are client.<namespace>.<method>;
reply types come from source, not the .d.ts; ten redis-py methods raise NotImplementedError;
an NRedisStack async entry is never a copy of the sync one, and the scan overloads return
IAsyncEnumerable.

Directive: when a sweep finds a client convention that is not in client-quirks.md, add it there in the same PR
Ticket: DOC-7267
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
andy-stark-redis added a commit that referenced this pull request Nov 6, 2026
The sweep behind #4482 and #4476 left four kinds of defect in the nredisstack lists, found by
checking each entry against NRedisStack 1.8.0 and StackExchange.Redis 3.4.31 by reflection.
152 command files change; no other client key and only SUBSTR in the status file.

Removed: 30 expression-text entries, lines copied out of method bodies such as
StringIncrement(key, -value, flags) with return type "return" and every param typed Any (INCR,
INCRBY, INCRBYFLOAT, GET, HINCRBYFLOAT, ZINCRBY, ZREM, JSON.SET and the blocking list commands);
16 Async-named entries that had landed in sync lists (BITCOUNT, BITOP, GEODIST, SETBIT and
others, each with a sync twin already present); 4 GetRange(double value, Exclude exclude,
bool isStart) entries, a private sorted-set helper that GETRANGE and SUBSTR had picked up; 3
async HSCAN, SSCAN and ZSCAN entries that were the synchronous four-argument overload under its
sync name; and 325 exact duplicates inside a single list, up to three copies of one signature.

Replaced: KEYS and SCAN described a Keys(pattern, pageSize, cursor, pageOffset, flags) with no
database parameter and an async twin that was not named KeysAsync. The method is IServer.Keys
(database = -1 first), which issues KEYS or SCAN depending on the server, and the async form is
KeysAsync returning IAsyncEnumerable. Both now say so. SUBSTR had only the helper entry, and
neither library has a SUBSTR method, so its two lists are empty and the status file marks both
generic_only.

Added: 37 async entries for the 30 commands that had a sync list and no async key, the 7
blocking list and sorted-set pops (BLPopAsync and the others, which are NRedisStack extension
methods on IDatabase) and the 23 JSON.* commands (IJsonCommandsAsync). Each takes its sync
entry's params and descriptions with Async added to the name, and every one matches a method on
the released assembly by parameter names and types. JSON.GET's sync return type "public T?" is
now "T?".

Learned: copying entries by list index let a sync list absorb async entries and an async list absorb sync ones, so check names and duplicates after any bulk rewrite
Constraint: IServer.Keys is the only SE.Redis method for KEYS and SCAN, there is no Scan method
Directive: do not list a private helper or a line copied from a method body as an API entry, check the entry against the released assembly
Gaps: overload selection per command was not reviewed (INCRBYFLOAT still lists the long overload, HINCRBY lists HashDecrement)
Gaps: JSON.SET lists only the RedisValue overload, not the object overload or the fpha parameter that 1.8.0 has
Gaps: scan entries still show the source default RedisBase.CursorUtils.DefaultLibraryPageSize instead of 250
Recheck: when NRedisStack ships a release after 1.8.0, rerun the reflection check
Ticket: DOC-7267
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
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