-
Notifications
You must be signed in to change notification settings - Fork 11.5k
Description
Laravel Version
7
PHP Version
7.4
PhpRedis
5.3.1
Redis cluster
6.2.6
Database Driver & Version
No response
Description
I'll try to test on other environments later, if needed
Broadcasting script defined in \Illuminate\Broadcasting\Broadcasters\RedisBroadcaster::broadcastMultipleChannelsScript() does not follows guidelines for EVAL (see https://redis.io/commands/eval/). It passes channel names as ARGV, while they should be KEYS. The problem is visible, only when you switch to redis cluster. When specified channel names maps to multiple slots, this can lead to random dies of php. In some cases it dies with 139 (SIGSEGV). In some cases it throws exception The slot XXX is not covered by any node in this cluster
, where XXX has inadequate values like 22506 or -3899. In some cases script will fail with MOVED error.
The simpliest way to fix is to use
foreach ($this->formatChannels($channels) as $channel) {
$connection->client()->publish($channel, $payload);
}
instead of
$connection->eval(
$this->broadcastMultipleChannelsScript(),
0, $payload, ...$this->formatChannels($channels)
);
Steps To Reproduce
- Setup redis-cluster with 3 nodes
- Setup redis-cluster connection via phpredis (predis does not support publish or eval)
- Setup broadcasting to use cluster connection
- Create event with 2+ broadcast channels
public function broadcastOn()
{
return [new PrivateChannel('channel1'), new PrivateChannel('channel2'), ...];
}
- Subscribe to event in redis-cli
SUBSCRIBE private-channel1 private-channel2 ...
- Try to broadcast this event.
- See if message is received, and php is not crashed