Mismatched `group_discard` behavior on RedisPubSub and core Redis layers
nbhargava opened this issue · comments
Versions:
channels
4.0.0channels-redis
4.0.0
With RedisChannelLayer
, group_discard
explicitly does nothing if the channel is not in the group:
async def group_discard(self, group, channel):
"""
Removes the channel from the named group if it is in the group;
does nothing otherwise (does not error)
"""
assert self.valid_group_name(group), "Group name not valid"
assert self.valid_channel_name(channel), "Channel name not valid"
key = self._group_key(group)
connection = self.connection(self.consistent_hash(group))
await connection.zrem(key, channel)
In contrast, RedisPubSubChannelLayer
will assert and fail if that's not the case:
async def group_discard(self, group, channel):
"""
Removes the channel from a group.
"""
group_channel = self._get_group_channel_name(group)
assert group_channel in self.groups
group_channels = self.groups[group_channel]
assert channel in group_channels
group_channels.remove(channel)
if len(group_channels) == 0:
del self.groups[group_channel]
shard = self._get_shard(group_channel)
await shard.unsubscribe(group_channel)
For improved end-user expectations, they should both do the same thing. In my opinion, the original behavior of do nothing is more predictable and user-friendly, as any user of this library would have to otherwise functionally maintain self.groups
on their own independently in order to verify that sending a group_discard
method will not yield a crash.
If this change seems reasonable, I'm happy to put up a PR to this effect.
Via the Channel Layer spec:
A channel layer implementing the groups extension must also provide:
...
coroutine group_discard(group, channel)
, that removes the channel from the group if it is in it, and does nothing otherwise.
Looks like the PubSub layer behaviour is wrong.
If this change seems reasonable, I'm happy to put up a PR to this effect.
Yes please. 🎁