Skip to content

DOC-7170 Add compare-and-swap/compare-and-delete example to the strings page - #4240

Merged
andy-stark-redis merged 2 commits into
mainfrom
DOC-7170
Oct 12, 2026
Merged

andy-stark-redis merged 2 commits into
mainfrom
DOC-7170

Conversation

@andy-stark-redis

@andy-stark-redis andy-stark-redis commented Oct 9, 2026 •

Copy link
Copy Markdown
Contributor

Adds a compare-and-swap / compare-and-delete example (Redis 8.4 SET ... IFEQ and DELEX ... IFEQ) to the strings data type page, and refreshes the command-API mappings for SET, DELEX, and DIGEST. Jira: DOC-7170

Changes

  • strings/_index.md: new cas_cad step after setnx_xx, with short prose linking SET, DELEX, and DIGEST. The setnx_xx description no longer calls NX/XX "compare-and-set".
  • Client examples in local_examples/ for Python, Node.js, Jedis, Lettuce async and reactive, Go, SE.Redis, PHP, Rust sync and async.
  • Ruby is excluded with a lang_filter allowlist. redis-rb 6.0.0 doesn't ship ifeq:/delex; they're on master only.
  • API mappings:
    • SET: adds go-redis SetArgs and SetIFEQ/SetIFNE/SetIFDEQ/SetIFDNE, plus redis-rs set_options.
    • DELEX: adds node-redis and redis-rs.
    • DIGEST: adds Jedis and node-redis. Replaces the wrong Lettuce rows: they were the Lua-script SHA1 digest(String script), not the DIGEST command (digestKey).
    • Clears an invented Jedis delex return description.
  • PHP setnx_xx: fixes the same wrong // >>> (null) output comment in the existing step; it now uses var_export and NULL.
  • TCE skill: testing.md now closes stdin on the documented codex exec command and covers the capacity retry and one-client-per-verdict schema.
  • Harness: bumps the StackExchange.Redis pin from 3.0.0 to 3.3.1. In 3.0.0, ValueCondition is [Experimental], so it fails the build with SER002.

Verification

  • All 11 set_tutorial clients pass in the portable harness against Redis 8.8 (Ruby's existing steps included). The CLI block was checked against the live server.
  • Hugo build: the new block renders 10 client tabs plus the CLI tab, with no Ruby tab and no leaked scaffolding.
  • Codex reviewed each client file. One high finding was fixed: the PHP null output comment. One was declined: Rust .expect(), which matches the existing visible step.

Follow-ups

  • Add Ruby once redis-rb releases ifeq:/delex/digest.

🤖 Generated with Claude Code


Note

Low Risk
Documentation, generated examples, and API metadata updates with a test-harness dependency bump; no production runtime or auth changes.

Overview
Adds compare-and-swap / compare-and-delete documentation for Redis 8.4 (SET … IFEQ, DELEX … IFEQ) on the strings data-type page, including a new cas_cad tabbed example (Ruby omitted via lang_filter until redis-rb ships support).

Docs & examples: New prose and CLI block on strings/_index.md; the setnx_xx blurb no longer labels NX/XX as compare-and-set. Matching cas_cad steps land in Python, Node, Jedis, Lettuce async/reactive, Go, SE.Redis, PHP, and Rust sync/async. PHP also fixes setnx_xx null output to use var_export / NULL.

API mappings: Extends SET (go-redis conditional helpers, redis-rs set_options), DELEX (node-redis, redis-rs), and DIGEST (Jedis/node-redis; Lettuce entries corrected from script SHA1 digest to key digestKey). Clears incorrect Jedis delex return text.

Tooling: Bumps StackExchange.Redis in the dotnet harness to 3.3.1 so ValueCondition is not experimental. TCE testing guide documents codex exec pitfalls (< /dev/null, capacity errors, one client per invocation, unsandboxed $TMPDIR).

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

…gs page

Adds a cas_cad step to set_tutorial (SET IFEQ success and failure, then DELEX IFEQ miss and hit) for the 10 clients with released support, rewords the setnx_xx description that called NX/XX "compare-and-set", and refreshes the SET/DELEX/DIGEST API mappings. Every client step was run against Redis 8.8 in the portable harness, the CLI block was checked against the live server, and Codex reviewed each client file.

Ruby is kept off the step with a lang_filter allowlist because redis-rb 6.0.0 has no ifeq:/delex/digest; they exist only on master. Released support was checked at each client's latest tag, not the default branch: redis-py 8.1.0, Jedis 8.0.2, Lettuce 7.8.0, go-redis 9.23.0, node-redis 6.2.1, SE.Redis 3.3.1, redis-rs 1.7.1, Predis 3.7.0.

Client surprises the code depends on. In Lettuce reactive a failed condition is a null reply, which is an empty Mono, so any later flatMap silently never runs; the failing SET uses hasElement() to keep the chain alive. In go-redis a failed SetIFEQ comes back as the redis.Nil error, not an empty status, so the step prints err == redis.Nil. SE.Redis returns bool for both StringSet and StringDelete rather than OK/nil and 0/1. PHP echo of null prints an empty line, so the step uses var_export with NULL (as DtArraysTest.php does). The existing setnx_xx step in the same file still claims "(null)" and is left alone. redis-py 8.x and go-redis still label these APIs experimental.

The harness pinned StackExchange.Redis 3.0.0, where ValueCondition carries [Experimental] and SER002 is a build error. 3.1.0 removed the attribute, so the pin moves to the current 3.3.1. Readers on 3.0.x would need to suppress SER002.

The mapping refresh also fixed a wrong DIGEST entry: the Lettuce rows were digest(String script), the SHA1 helper for Lua scripts, not the DIGEST command; the command is digestKey(K key). Jedis delex had an invented return description ("The value of key"), which is now empty. New rows follow the neighboring core-string style (node_redis as DELEX(...)/DIGEST(...) returning Any), not the newer AR* camelCase style.

Codex flagged rust-sync's .expect() calls as test scaffolding. That was rejected: the visible setnx_xx step in the same file already uses .expect, and the reviewer for rust-async passed the identical code.

Learned: Lettuce reactive null replies are empty Monos, so later flatMaps never run; SE.Redis ValueCondition was experimental (SER002) before 3.1.0
Constraint: cas_cad lang_filter must list every supporting client by exact config.toml display name, because a client file lacking the step renders the whole file
Rejected: dropping .expect() in the Rust cas_cad steps | consistent with the existing visible setnx_xx step, and idiomatic for examples
Directive: the PHP setnx_xx step's "// >>> (null)" comment is wrong too (echo of null prints nothing) and needs the same var_export fix
Recheck: when redis-rb ships ifeq:/delex/digest (post-6.0.0), add Ruby to cas_cad and the SET/DELEX/DIGEST mappings
Gaps: fidelity mode was not run, only portable; first-supporting version per client was not established, only latest-release support
Ticket: DOC-7170
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@github-actions

github-actions Bot commented Oct 9, 2026 •

Copy link
Copy Markdown
Contributor

DOC-7170

@github-actions

github-actions Bot commented Oct 9, 2026

Copy link
Copy Markdown
Contributor

@github-actions

github-actions Bot commented Oct 9, 2026 •

Copy link
Copy Markdown
Contributor

🧠 Redis Memory

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

Memory updated at d6b91b1

@andy-stark-redis andy-stark-redis self-assigned this Oct 9, 2026
@andy-stark-redis andy-stark-redis added the clients Client library docs label Oct 9, 2026
The PHP setnx_xx step echoed a null reply with string interpolation, which prints an empty line, yet its comment claimed "(null)". It now uses var_export and NULL, the same as the cas_cad step and DtArraysTest.php. The tce-examples testing reference now closes stdin on the documented codex exec command and records the three failures hit on this PR: the stdin hang, transient "model at capacity" exits with no verdict file, and the one-client-per-verdict schema.

Ticket: DOC-7170
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
andy-stark-redis added a commit that referenced this pull request Oct 12, 2026
…tterns

Two client gotchas from the DOC-7170 cas_cad example (PR #4240), which until now were recorded only in that commit. In Lettuce reactive, a nil reply is an empty Mono, so later flatMap/doOnNext steps silently never run and the test still passes; show the result with hasElement() or defaultIfEmpty(). In Predis, echo of null prints an empty line, so "// >>> (null)" comments are wrong; use var_export and NULL.

Ticket: DOC-7172
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@andy-stark-redis
andy-stark-redis merged commit c512339 into main Oct 12, 2026
99 checks passed
@andy-stark-redis
andy-stark-redis deleted the DOC-7170 branch October 12, 2026 10:44
andy-stark-redis added a commit that referenced this pull request Oct 13, 2026
Updates the tce-examples and command-api-mapping skill reference files with facts that
were stale or missing during recent example work.

From the HIMPORT work in PR #4242:
- tce-examples gets the Ruby 3.4+ hash inspect format and a new section listing the
  harness client pins that predate HIMPORT, with the isolated scratch-project
  workaround to use until they're raised.
- command-api-mapping gets the redis_rb client ID and its source location, and a new
  ioredis section on typed-subcommand rows.
- It also corrects three facts: node-redis method names come from the
  commands/index.ts export, which sometimes has JSDoc; async versions of void
  SE.Redis methods return plain Task; and Predis container methods live in
  src/Command/Container.

From the DOC-7170 cas_cad example (PR #4240), two null-reply gotchas that were
previously recorded only in that commit:
- In Lettuce reactive, a nil reply is an empty Mono, so later steps silently never
  run.
- In Predis, echo of null prints an empty line, so use var_export.

Raising the harness pins themselves is left to a separate change.

Ticket: DOC-7172
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

clients Client library docs

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants