Skip to content

[PHP] Complete sharded Pub/Sub: SHARDNUMSUB, SSUBSCRIBE, SUNSUBSCRIBE, SPUBLISH + investigate NUMSUB/SHARDNUMSUB counts #329

Description

Summary

Follow-up to #306 / #327, which implemented PUBSUB SHARDCHANNELS. This issue tracks the remaining sharded Pub/Sub work in the PHP client and a related subscriber-count problem uncovered during that work.

Remaining work (checklist)

  • Investigate incorrect PUBSUB NUMSUB / PUBSUB SHARDNUMSUB subscriber counts in cluster mode.
  • Implement SSUBSCRIBE (sharded subscribe).
  • Implement SUNSUBSCRIBE (sharded unsubscribe).
  • Implement sharded publish SPUBLISH.
  • Implement PUBSUB SHARDNUMSUB.
  • Add full behavioral tests for SHARDNUMSUB (non-zero counts, numsub vs shardnumsub separation) using PHP-native sharded subscriptions.

Detail 1 — Incorrect NUMSUB / SHARDNUMSUB subscriber counts in cluster mode

Symptom
With an active subscriber, both commands return an empty channel name and a zero count instead of the real channel and count:

$c = new ValkeyGlideCluster(addresses: [['host' => '127.0.0.1', 'port' => 7001]]);
// with an active subscriber on 'mychan':
var_export($c->pubsub('numsub', ['mychan']));
// Expected: ['mychan', 1]
// Actual:   ['', 0]

This affects the pre-existing PUBSUB NUMSUB as well as PUBSUB SHARDNUMSUB.

Reproduction

  1. Start a 6-node cluster (Valkey 7.0+).
  2. valkey-cli -c -p 7001 subscribe mychan (or ssubscribe mychan for the shard variant).
  3. Query via the PHP client (example above).

Investigation so far

  • These commands route with RouteBy::AllNodes + ResponsePolicy::CombineMaps in glide-core; the reply is a flat [channel, count] per node, combined across nodes.
  • FFI-level inspection of the combined CommandResult showed a Map whose single element had an empty String key and value 0.
  • Querying the slot-owner node directly (single node, no combine) returns the correct [channel, 1].
  • The Python client's cluster tests assert correct per-channel counts with no special client-side handling, which suggests glide-core aggregates correctly for other clients. This points the investigation toward the PHP binding / FFI response conversion rather than glide-core — to be confirmed by reproducing in a second client (Python/Go) against the same cluster.

Impact

  • Incorrect subscriber counts from NUMSUB/SHARDNUMSUB in cluster mode.
  • Blocks accurate behavioral testing of SHARDNUMSUB.

Detail 2 — Missing sharded Pub/Sub commands in PHP

Implemented in Java/Node/Python/Go and supported by the FFI/core (SPublish=909, SSubscribe=910, SUnsubscribe=912, SSubscribeBlocking=918, SUnsubscribeBlocking=919), but stubbed/absent in PHP.

Command FFI request type PHP status
SSUBSCRIBE SSubscribe=910, SSubscribeBlocking=918 Empty stub: PHP_METHOD(ValkeyGlide, ssubscribe) { /* TODO: Implement */ } (valkey_glide.c); stub declaration commented out (valkey_glide.stub.php)
SUNSUBSCRIBE SUnsubscribe=912, SUnsubscribeBlocking=919 Not implemented; stub commented out (valkey_glide.stub.php)
SPUBLISH SPublish=909 Not implemented; publish(string $channel, string $message): int has no sharded flag (valkey_glide.stub.php)

Consequence: no PHP-native way to create a sharded subscriber or publish to a shard channel, which blocks end-to-end behavioral testing of the sharded introspection commands from PHP.

Tasks

  • Implement ssubscribe(array $channels, callable $cb): bool using the blocking-loop callback model that subscribe uses.
  • Implement sunsubscribe(array $channels): ValkeyGlide|array|bool.
  • Implement sharded publish (confirm PHPRedis-compatible signature: a sharded flag on publish() vs. a dedicated spublish()).
  • Add integration tests mirroring the other-language sharded pub/sub suites.

Detail 3 — Implement PUBSUB SHARDNUMSUB and complete test coverage

Depends on Detail 1 and Detail 2.

Tasks

  • Implement PUBSUB SHARDNUMSUB (currently returns a "not yet supported" error).
  • Add behavioral tests: non-zero shard subscriber counts and numsub vs shardnumsub separation, using PHP-native ssubscribe, mirroring the Python suite.

References

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions