Repository navigation
fix(microservices): reply on the request channel when redis wildcards are enabled - #17866
Merged
kamilmysliwiec merged 2 commits intoSep 24, 2026
Merged
Conversation
… are enabled
ioredis emits "pmessage" with (pattern, channel, message). With wildcards
enabled the handler is registered on the pattern ("users.*"), so looking
the handler up by the pattern is correct, but the reply was published to
"users.*.reply" as well. Redis does not expand globs on PUBLISH, while
ClientRedis subscribes to the reply channel of the concrete channel it
published to ("users.created.reply"), so the response never arrived and
every request-response call against a wildcard handler timed out.
Publish the reply to the channel the request came from, which is what the
mqtt server already does. Without wildcards both values are the same
channel, so nothing changes there.
fadiroot
force-pushed
the
fix/redis-wildcard-reply-channel
branch
from
September 24, 2026 09:59
830eac7 to
7316961
Compare
4 of 12 tasks
kamilmysliwiec
added a commit
that referenced
this pull request
Oct 13, 2026
…ds (#18125) * fix(microservices): ignore a redis server's own replies under wildcards With wildcards enabled, ServerRedis psubscribes to the handler pattern (e.g. "users.*") and, since #17866, replies on the concrete request channel plus ".reply" ("users.x.reply"). A Redis glob "*" matches dots too, so the server received its own reply. The deserializer mapped the { response, isDisposed, id } packet to an event on "users.*", and the request handler ran a second time with the reply as its data. handleMessage now skips a message on a ".reply" channel that has no handler of its own when the raw packet has an id and no pattern, which is the shape of every reply this server publishes. Requests, events and messages without an id on such channels are still dispatched. * fix(microservices): decide own redis replies by the subscription Moves the check into isOwnReply(). It now looks at the subscription pattern rather than whether the reply channel has a handler, so a "*.reply" subscription still receives replies and "users.*" skips them even when "users.x.reply" has a handler. --------- Co-authored-by: Kamil Myśliwiec <mail@kamilmysliwiec.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
PR Checklist
Please check if your PR fulfills the following requirements:
PR Type
What kind of change does this PR introduce?
What is the current behavior?
Issue Number: N/A
With
wildcards: true,ServerRedislistens forpmessage, which ioredis emits as(pattern, channel, message). The handler is registered on the pattern (e.g.users.*) and is looked up correctly, but the reply for a request-response message is also published tousers.*.reply.Redis does not expand globs on
PUBLISH, andClientRedissubscribes to the reply channel of the concrete channel it published to (users.created.reply), so the reply never reaches the client and everyclient.send()against a wildcard handler hangs until it times out. Events are unaffected because they do not reply.Repro:
What is the new behavior?
The reply is published to the channel the request came from (
users.created.reply), which is whatServerMqttalready does for its wildcard topics. Without wildcards the channel and the pattern are the same value, so nothing changes there.A unit test covers the wildcard case in
server-redis.spec.ts.Does this PR introduce a breaking change?
Other information