Skip to content

DOC-7172 Add cross-client HIMPORT bulk-import examples and API mappings - #4242

Open
andy-stark-redis wants to merge 1 commit into
mainfrom
DOC-7172
Open

andy-stark-redis wants to merge 1 commit into
mainfrom
DOC-7172

Conversation

@andy-stark-redis

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

Copy link
Copy Markdown
Contributor

Adds client examples for bulk hash import with HIMPORT (Redis 8.10). Most client libraries now support it, and Jedis has a good example in its own docs, but our docs had no code for it. Part of the DOC-7164 effort to consolidate client library information. Ticket: DOC-7172.

Changes

  • data-types/hashes.md: the "Bulk import with HIMPORT" section gets two tabbed code examples:

    • himport_basic: declare the field names once, import three users, and read one back.
    • himport_pipeline: import 1,000 users in one pipeline.

    New prose between them covers four points:

    • an import replaces an existing key;
    • HGETALL field order isn't guaranteed;
    • clients declare fieldsets on each connection for you, and most mark the API experimental;
    • send large imports in a pipeline (links to the pipelining page).
  • Tabs: redis-py, node-redis, ioredis, go-redis, Jedis, Lettuce (sync, async, reactive), StackExchange.Redis (sync, async), Predis, and redis-rb. There's no Rust tab, because redis-rs has no HIMPORT support. phpredis support is unreleased.

  • API mapping: new files for HIMPORT PREPARE/SET/DISCARD/DISCARDALL, read from source at each client's first HIMPORT release, plus the regenerated merged file. Jedis, Lettuce and SE.Redis appear only under SET, because they have no prepare or discard methods.

Notes for reviewers

  • The tabs don't all look alike, on purpose. Jedis, Lettuce and SE.Redis use a fieldset object instead of a PREPARE call. ioredis declares fieldsets in its constructor, so that call is visible in each step. Predis and redis-rb send PREPARE inside the pipeline, as their READMEs recommend.
  • Lettuce sync has no pipeline API, so its pipeline step is a plain loop, with a comment pointing to the async or reactive API.
  • HGETALL order: Redis 8.10.1 returns age, name, email, not the declared order. The output comments show what each client actually prints.
  • Upstream doc issues, not filed:
    • The Lettuce HashImport javadoc says try-with-resources is safe for reactive. It isn't if you subscribe after the block closes; the example avoids this.
    • SE.Redis docs/HImport.md still has a buffer-reuse caveat that 3.2.0 made unnecessary.

Testing

  • Run against Redis 8.10.1: every file passed, using each client's first HIMPORT release: redis-py 8.1.0, node-redis 6.2.0, ioredis 6.0.0, go-redis 9.22.0, Jedis 8.0.0, Lettuce 7.7.0, SE.Redis 3.3.1 and 3.0.25, Predis 3.6.0, and redis-rb 6.0.0.
    • The shared harness's client pins predate HIMPORT, so each client was tested in an isolated scratch project with its own Redis container, not with run.sh. Raising those pins is a follow-up.
  • Codex review: each file was reviewed separately. The one high finding, a misleading Lettuce sync comment, was fixed and re-reviewed clean.
  • Site build: build/make.py and hugo both build cleanly. Every tab renders both steps, no test scaffolding shows, and API methods appear on all four HIMPORT subcommand pages.

🤖 Generated with Claude Code


Note

Low Risk
Documentation and generated API metadata only; no runtime or server behavior changes.

Overview
Adds cross-client documentation for bulk hash import with HIMPORT in the compact-hashes section of hashes.md.

The Bulk import with HIMPORT section now includes two tabbed clients-example steps (himport_basic, himport_pipeline) plus prose on replace semantics, non-guaranteed HGETALL order, per-connection fieldsets, experimental APIs, and pipelining for large loads.

New local_examples/hash_import samples cover redis-py, node-redis, ioredis, go-redis, Jedis, Lettuce (sync/async/reactive), StackExchange.Redis (sync/async), Predis, and redis-rb, reflecting client-specific patterns (fieldset objects vs PREPARE, ioredis constructor config, PREPARE inside pipelines where needed).

Command API mapping adds entries for HIMPORT PREPARE, SET, DISCARD, and DISCARDALL (per-command JSON files and the merged command-api-mapping.json), with Jedis/Lettuce/SE.Redis mapped mainly on SET.

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

Adds a hash_import example set (steps himport_basic and himport_pipeline) to the
"Bulk import with HIMPORT" section of data-types/hashes.md. It covers 12 tabs plus the
CLI: redis-py, node-redis, ioredis, go-redis, Jedis, Lettuce sync/async/reactive,
SE.Redis sync/async, Predis and redis-rb. Rust is left out because redis-rs has no
HIMPORT support, and phpredis because its support is unreleased. The page prose now
covers the overwrite semantics, field order, client-managed fieldsets and pipelining.
Also adds API-mapping files for HIMPORT PREPARE/SET/DISCARD/DISCARDALL, read from
source at each client's first HIMPORT release.

Every file was run against Redis 8.10.1 at its client's first HIMPORT release:
redis-py 8.1.0, node-redis 6.2.0, ioredis 6.0.0, go-redis 9.22.0, Jedis 8.0.0,
Lettuce 7.7.0, SE.Redis 3.3.1 and 3.0.25, Predis 3.6.0, redis-rb 6.0.0. Each file
was also reviewed separately by Codex. The shared harness could not run them,
because it pins older clients (Jedis 7.5.3, SE.Redis 3.0.0, node-redis 6.1,
ioredis 5.11, go-redis 9.18). Each file was tested in an isolated scratch project
with its own Redis 8.10 container instead.

The surprise: HGETALL on a compact hash returns age, name, email, not the PREPARE
order. That order was the same across fresh runs, but nothing guarantees it, so
every assertion is order-independent. The output comments show what each client
really prints.

The clients split into two models. redis-py, go-redis, node-redis, Predis and
redis-rb mirror the CLI with prepare and set. Jedis, Lettuce and SE.Redis have
no PREPARE method: you create a HashImport object and the client sends PREPARE
lazily per connection. So the Java and .NET clients appear only in the HIMPORT
SET mapping. ioredis manages only fieldsets declared in its constructor, which
is why that call is visible in each step and not hidden.

Pipelines differ per client:
- Predis and redis-rb put PREPARE inside the pipeline, as their READMEs say, and
  drop its reply before counting.
- node-redis uses Promise.all, because execAsPipeline does not auto-prepare in
  6.2.0 (a TODO in registry.ts).
- Lettuce sync has no pipeline API, so its pipeline step is a loop with a comment
  saying so.

Lettuce reactive himportSet checks the fieldset at subscribe time. A Mono blocked
after try-with-resources closes throws IllegalStateException, even though the
HashImport javadoc says try-with-resources is safe for reactive.

Learned: compact-hash HGETALL order differs from PREPARE order; output comments are observed, asserts are order-independent
Learned: the harness pins predate HIMPORT, so these files were verified in per-client scratch projects, not run.sh
Constraint: Lettuce reactive must block()/subscribe inside the HashImport try block, or the import throws IllegalStateException
Constraint: SE.Redis files carry no SER008 pragma because NRedisStack main pins SE.Redis 3.3.1; on 3.0.25-3.2.15 they fail to compile
Constraint: SE.Redis examples allocate a new RedisValue[] per row; on 3.0.25-3.1.x a reused buffer is aliased until the batch executes
Rejected: db.WaitAll in the SE.Redis sync batch | SE.Redis 3.3.1 analyzer flags it SER308 (sync-over-async); Task.WaitAll only raises the test-only xUnit1031
Rejected: multi().execAsPipeline() for node-redis | it does not auto-prepare HIMPORT in 6.2.0
Rejected: mapping HashImport.of/Create to HIMPORT PREPARE | it builds a local object and sends nothing to the server
Directive: before running hash_import through run.sh, raise the harness client pins to the versions listed in the body
Recheck: when Jedis/Lettuce/redis-py/node-redis/go-redis/Predis/redis-rb drop the experimental marking on HIMPORT
Recheck: when node-redis execAsPipeline/multi gains HIMPORT auto-prepare (registry.ts TODO himport-multi)
Ticket: DOC-7172
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@andy-stark-redis andy-stark-redis added the clients Client library docs label Oct 9, 2026
@github-actions

github-actions Bot commented Oct 9, 2026 •

Copy link
Copy Markdown
Contributor

DOC-7172

@github-actions

github-actions Bot commented Oct 9, 2026 •

Copy link
Copy Markdown
Contributor

🧠 Redis Memory

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

Memory updated at 72b1c08

@github-actions

github-actions Bot commented Oct 9, 2026

Copy link
Copy Markdown
Contributor

@andy-stark-redis
andy-stark-redis requested a review from a team October 9, 2026 15:55
@andy-stark-redis andy-stark-redis self-assigned this Oct 9, 2026
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