Skip to content

Redis Connection incorrectly reporting multiple groups #47807

Closed
@lfjeff

Description

@lfjeff

Symfony version(s) affected

5.4.13

Description

Symfony\Component\Messenger\Bridge\Redis\Transport\Connection is incorrectly throwing a "More than one group exists for stream" exception.

There is apparently a subtle difference between the PHP $this->connection->xinfo('GROUPS, $this->stream) method and the CLI XINFO GROUPS streamname command.

When I run the command line version, it only reports one group:

127.0.0.1:6379> XINFO GROUPS messages
1) 1) "name"
   2) "symfony"
   3) "consumers"
   4) (integer) 5
   5) "pending"
   6) (integer) 1
   7) "last-delivered-id"
   8) "1665103915330-0"

However, when I run the PHP version, it reports an extra group that I deleted:

$groups = $this->connection->xinfo('GROUPS', $this->stream);

results in:

"groups":[{"name":"high","consumers":0,"pending":0,"last-delivered-id":"0-0"},{"name":"symfony","consu
mers":20,"pending":1,"last-delivered-id":"1664986563471-0"}]

The extra "high" group that is reported by PHP was one that I created and then deleted with the XGROUP DESTROY messages high command.

Regardless of what I did to try and delete the "high" group, the PHP xinfo() command still reported it.

To fix the problem, I finally had to stop Redis, delete the.aof and .rdb files, and then restart.

How to reproduce

  1. Create an extra Redis group under the messages stream, then destroy it.

  2. Create a connection to Redis and perform a get() or add()

Possible Solution

I'm not a Redis expert, so there may be better way to completely delete a group and leave no traces.

If there is not, I would suggest making the setup() method a little smarter in how it detects multiple active groups.

Instead of just doing a 1 < \count($groups) , it could do a more detailed check of each group and ignore any that have their consumers, pending and last-delivered-id set to zero. Something like this:

if (\is_array($groups) {
    $groupCount = 0;
    foreach ($groups as $group) {
        if ($group['consumers'] == 0 && $group['pending'] == 0 && $group['last-delivered-id'] == '0-0') {
            continue;
        }
        $groupCount++;
    }
    if ($groupCount > 1) {
       throw new LogicException(....);
    }
}

Additional Context

No response

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions