Skip to content

Commit

Permalink
Rewrite async callback queue (push/shift) to not do allocations
Browse files Browse the repository at this point in the history
The callback queue in the changed so that each callback is allocated once and
freed once. The operations "push" and "shift" don't copy the callback struct
between heap and stack, but instead they and just set the 'next' pointer to link
callbacks into a list, without doing any allocations. For pubsub channels, one
callback can be mapped to multiple channels, and they can be unsubscribed
independently, so we use a reference counter to keep track of references to a
callback.

This prepares for adding finalizer support and to be sure it is called only
once, when the callback is freed.

The way hiredis kept tack of 'pubsub mode' using `pending_subs` and
`unsubscribe_sent` was flawed. It couldn't handle multiple pending subscribe
commands with an overlapping but different set of channels and it couldn't
handle an error reply to a SUBSCRIBE or UNSUBSCRIBE command. Now we change this
so that all commands, even SUBSCRIBE and UNSUBSCRIBE, are added to the reply
queue and the 'subscribe' and 'unsubscribe' replies are matched against them in
the queue. The channel-to-callback dicts are updated when a 'subscribe' or
'unsubscribe' reply is received, confirming that the client has subscribed or
unsubscribed to a channel, rather than when the command is sent. This change
makes it possible to handle an error reply for a pubsub command.

With this change, there is no need to keep a different replies queue for
subscribe commands and regular commands. All are added to the same replies
queue.
  • Loading branch information
zuiderkwast committed Jul 19, 2023
1 parent dedc620 commit 342cb92
Show file tree
Hide file tree
Showing 2 changed files with 259 additions and 267 deletions.
Loading

0 comments on commit 342cb92

Please sign in to comment.