kinetis / redis
A non-replaying, deadline-bounded Redis transport for amphp/redis, with TLS, authentication, and Redis Cluster slot routing. Usable standalone, not only with Kinetis.
Requires
- php: ^8.4
- amphp/amp: ^3.1.3
- amphp/redis: ^2.0.4
- amphp/socket: ^2.4.0
- revolt/event-loop: ^1.0.9
Requires (Dev)
- infection/infection: ^0.35.0
- kinetis/framework: ^1.5.0
- phpstan/phpstan: ^2.2.8
- phpunit/phpunit: ^12.5.33
- vimeo/psalm: ^6.16.1
Suggests
None
Provides
None
Conflicts
None
Replaces
None
README
kinetis/redis
A non-replaying, deadline-bounded Redis transport with Cluster routing
Part of Kinetis, a non-blocking PHP framework for API-first applications, developed in the kinetis-dev/kinetis monorepo.
Usable by any Revolt-based project: it depends on amphp/redis,
amphp/socket and the event loop, never on
kinetis/framework.
amphp/redis's own ReconnectingRedisLink re-sends every queued command
after a connection loss, so a command whose outcome is unknown can be
applied twice — a double INCR, a queue job pushed twice. This package
replaces that transport and adds Redis Cluster routing on top of it.
- A command is never re-sent after a connection failure. A failure
before the write is
ConnectionFailedand is safe to retry. A failure after it isOutcomeUnknown, and this package does not decide for you what to do about it. - One budget per operation covers connect, TLS,
AUTH,SELECT, the write, the reply, cluster discovery, and every redirect hop. - Pipelined and idle-clean. Concurrent fibers share one socket, FIFO;
an idle connection holds no event-loop reference, so
EventLoop::run()returns. - Cluster routing with
CLUSTER SLOTSdiscovery, MOVED/ASK, and a six-attempt bound. Routing keys are supplied by the caller, never guessed from a command's parameters. A pre-dispatchConnectionFaileddrops the slot map, so an owner it names that stops answering is routed around after one rediscovery.
use Kinetis\Redis\Client; use Kinetis\Redis\ClientOptions; use Kinetis\Redis\ClusterClient; use Kinetis\Redis\Endpoint; $client = Client::create(Endpoint::parse('127.0.0.1:6379'), new ClientOptions(timeout: 5.0)); $client->execute('SET', 'user.1', 'payload', 'EX', 60); $cluster = ClusterClient::create( [Endpoint::parse('10.0.0.1:6379'), Endpoint::parse('10.0.0.2:6379')], new ClientOptions(timeout: 5.0), ); $cluster->executeKeyed('user.1', 'GET', 'user.1');
amphp/redis's typed command facade composes over the same transport:
use Amp\Redis\RedisClient; $redis = new RedisClient($client->link()); $redis->set('user.1', 'payload');
Not in scope
No command facade, pub/sub, Sentinel, replica reads, MULTI, background
topology watching, cross-slot aggregation, or retry classification. Use
Amp\Redis\RedisClient over link() for typed commands.
Installation
composer require kinetis/redis
Requires PHP 8.4+. Full documentation: kinetis.dev/docs/redis.html.
License
MIT — see LICENSE.