A Redis client for Pony. Speaks RESP2 and RESP3, with pub/sub and pipelined commands.
This is a Pony project. The ponylang org maintains a set of LLM coding skills. Get set up with them before contributing:
-
Not set up yet? Install them once:
git clone https://github.com/ponylang/llm-skills.git cd llm-skills python install.py -
Already set up? Make sure you're on the latest. If you installed with the script above,
git pullin the directory where you clonedllm-skillsand the symlinked skills update automatically — if you set them up another way, refresh them however that setup expects.
See the llm-skills README for details and other harnesses.
When you start working on this project, load the pony-skills skill — it tells your assistant which Pony skill to use for each task.
Read CONTRIBUTING.md.
If you are running on an Anthropic model, use claude-opus-4-6 for writing comments, documentation, and other prose. Prose quality from Anthropic models dropped starting with Opus 4.7 and has gotten worse with each subsequent release.
Run make lint before considering any work done. Fix all issues it reports. make lint runs pony-lint, which checks for style and correctness problems in Pony source files. A clean lint run is part of "done" — don't open a PR or report completion with lint issues outstanding.
make ssl=3.0.x # build + run all tests (needs Redis running)
make unit-tests ssl=3.0.x # unit tests only (no Redis needed)
make test-one t=TestName ssl=3.0.x # run a single test by name
make integration-tests ssl=3.0.x # integration tests only (needs Redis)
make examples ssl=3.0.x # build examples
make start-redis # start plaintext, SSL, and RESP2-only Redis in Docker
make stop-redis # stop and remove them
make clean # clean build artifacts
ssl= is required on build targets (lori pulls in ssl), set to your installed TLS library: 4.0.x, 3.0.x, 1.1.x, or libressl. Add config=debug for a debug build.
Run the integration tests locally with make start-redis, then make test ssl=3.0.x, then make stop-redis. They read REDIS_* environment variables (see _RedisTestConfiguration), which default to 127.0.0.2 on Linux rather than the usual loopback, dodging the WSL2 mirrored-networking hang.
The Session actor is the entry point. It tracks connection and pub/sub lifecycle with explicit state classes, all in session.pony.
_SessionUnopened ──on_connected──► _SessionNegotiating (if Resp3)
──on_connected──► _SessionConnected (if Resp2 + password)
──on_connected──► _SessionReady (if Resp2, no password)
──on_failure──► _SessionClosed
_SessionNegotiating ──HELLO map──► _SessionReady
──HELLO error──► _SessionConnected (if password, send AUTH)
──HELLO error──► _SessionReady (if no password)
_SessionConnected ──AUTH OK──► _SessionReady
──AUTH error──► _SessionClosed
_SessionReady ──subscribe/psubscribe──► _SessionSubscribed
──close/error──► _SessionClosed
_SessionSubscribed ──unsub count 0──► _SessionReady
──close/error──► _SessionClosed
- Never connect with SSL to a plaintext Redis server, even in a test. The TLS ClientHello carries no
\r\n, so Redis's RESP parser buffers it forever waiting for a line terminator while the SSL client waits for a ServerHello — both block indefinitely. To exercise the SSL constructor path, connect to a non-listening port instead; connection-refused is fast and deterministic. - Backpressure tests use a fake server built on lori's listener/connection APIs, because real Redis fill rates vary by environment. The fake listener must track the connections it spawns and dispose them in
_on_closed(), or the test hangs. - Integration tests are named
integration/…and setexclusion_group() => "integration"; they need a running Redis.
- Impossible states call
_IllegalState()/_Unreachable()(_mort.pony). \nodoc\on test classes.