qruto/laravel-wave

[Bug]: Not working with predis

Closed this issue · 2 comments

What happened?

I use predis and there seems to be a difference with the interface.

[2024-03-13 13:22:45] production.ERROR: ERR wrong number of arguments for 'xdel' command {"exception":"[object] (Predis\\Response\\ServerException(code: 0): ERR wrong number of arguments for 'xdel' command at /path/vendor/predis/predis/src/Client.php:416)
[stacktrace]
#0 /path/vendor/predis/predis/src/Client.php(385): Predis\\Client->onErrorResponse()
#1 /path/vendor/predis/predis/src/Client.php(335): Predis\\Client->executeCommand()
#2 /path/vendor/laravel/framework/src/Illuminate/Redis/Connections/Connection.php(116): Predis\\Client->__call()
#3 /path/vendor/laravel/framework/src/Illuminate/Redis/Connections/Connection.php(216): Illuminate\\Redis\\Connections\\Connection->command()
#4 /path/vendor/qruto/laravel-wave/src/Storage/BroadcastEventHistoryRedisStream.php(65): Illuminate\\Redis\\Connections\\Connection->__call()
#5 /path/vendor/qruto/laravel-wave/src/Storage/BroadcastEventHistoryRedisStream.php(46): Qruto\\Wave\\Storage\\BroadcastEventHistoryRedisStream->removeOldEvents()
#6 /path/vendor/qruto/laravel-wave/src/BroadcastManagerExtended.php(30): Qruto\\Wave\\Storage\\BroadcastEventHistoryRedisStream->pushEvent()
#7 /path/vendor/laravel/framework/src/Illuminate/Broadcasting/BroadcastEvent.php(84): Illuminate\\Broadcasting\\Broadcasters\\RedisBroadcaster@anonymous->broadcast()
#8 /path/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(36): Illuminate\\Broadcasting\\BroadcastEvent->handle()
#9 /path/vendor/laravel/framework/src/Illuminate/Container/Util.php(41): Illuminate\\Container\\BoundMethod::Illuminate\\Container\\{closure}()
#10 /path/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(93): Illuminate\\Container\\Util::unwrapIfClosure()
#11 /path/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(35): Illuminate\\Container\\BoundMethod::callBoundMethod()
#12 /path/vendor/laravel/framework/src/Illuminate/Container/Container.php(661): Illuminate\\Container\\BoundMethod::call()
#13 /path/vendor/laravel/framework/src/Illuminate/Bus/Dispatcher.php(128): Illuminate\\Container\\Container->call()
#14 /path/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(141): Illuminate\\Bus\\Dispatcher->Illuminate\\Bus\\{closure}()
#15 /path/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(116): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()
#16 /path/vendor/laravel/framework/src/Illuminate/Bus/Dispatcher.php(132): Illuminate\\Pipeline\\Pipeline->then()
#17 /path/vendor/laravel/framework/src/Illuminate/Queue/CallQueuedHandler.php(123): Illuminate\\Bus\\Dispatcher->dispatchNow()
#18 /path/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(141): Illuminate\\Queue\\CallQueuedHandler->Illuminate\\Queue\\{closure}()
#19 /path/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(116): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()
#20 /path/vendor/laravel/framework/src/Illuminate/Queue/CallQueuedHandler.php(122): Illuminate\\Pipeline\\Pipeline->then()
#21 /path/vendor/laravel/framework/src/Illuminate/Queue/CallQueuedHandler.php(70): Illuminate\\Queue\\CallQueuedHandler->dispatchThroughMiddleware()
#22 /path/vendor/laravel/framework/src/Illuminate/Queue/Jobs/Job.php(98): Illuminate\\Queue\\CallQueuedHandler->call()
#23 /path/vendor/laravel/framework/src/Illuminate/Queue/Worker.php(425): Illuminate\\Queue\\Jobs\\Job->fire()
#24 /path/vendor/laravel/framework/src/Illuminate/Queue/Worker.php(375): Illuminate\\Queue\\Worker->process()
#25 /path/vendor/laravel/framework/src/Illuminate/Queue/Worker.php(326): Illuminate\\Queue\\Worker->runJob()
#26 /path/vendor/laravel/framework/src/Illuminate/Queue/Console/WorkCommand.php(147): Illuminate\\Queue\\Worker->runNextJob()
#27 /path/vendor/laravel/framework/src/Illuminate/Queue/Console/WorkCommand.php(130): Illuminate\\Queue\\Console\\WorkCommand->runWorker()
#28 /path/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(36): Illuminate\\Queue\\Console\\WorkCommand->handle()
#29 /path/vendor/laravel/framework/src/Illuminate/Container/Util.php(41): Illuminate\\Container\\BoundMethod::Illuminate\\Container\\{closure}()
#30 /path/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(93): Illuminate\\Container\\Util::unwrapIfClosure()
#31 /path/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(35): Illuminate\\Container\\BoundMethod::callBoundMethod()
#32 /path/vendor/laravel/framework/src/Illuminate/Container/Container.php(661): Illuminate\\Container\\BoundMethod::call()
#33 /path/vendor/laravel/framework/src/Illuminate/Console/Command.php(183): Illuminate\\Container\\Container->call()
#34 /path/vendor/symfony/console/Command/Command.php(312): Illuminate\\Console\\Command->execute()
#35 /path/vendor/laravel/framework/src/Illuminate/Console/Command.php(152): Symfony\\Component\\Console\\Command\\Command->run()
#36 /path/vendor/symfony/console/Application.php(1022): Illuminate\\Console\\Command->run()
#37 /path/vendor/symfony/console/Application.php(314): Symfony\\Component\\Console\\Application->doRunCommand()
#38 /path/vendor/symfony/console/Application.php(168): Symfony\\Component\\Console\\Application->doRun()
#39 /path/vendor/laravel/framework/src/Illuminate/Console/Application.php(102): Symfony\\Component\\Console\\Application->run()
#40 /path/vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php(155): Illuminate\\Console\\Application->run()
#41 /path/artisan(35): Illuminate\\Foundation\\Console\\Kernel->handle()
#42 {main}
"} 

and

production.ERROR: Array to string conversion {"userId":1,"exception":"[object] (ErrorException(code: 0): Array to string conversion at /path/vendor/predis/predis/src/Connection/StreamConnection.php:368)
[stacktrace]
#0 /path/vendor/laravel/framework/src/Illuminate/Foundation/Bootstrap/HandleExceptions.php(270): Illuminate\\Foundation\\Bootstrap\\HandleExceptions->handleError()
#1 [internal function]: Illuminate\\Foundation\\Bootstrap\\HandleExceptions->Illuminate\\Foundation\\Bootstrap\\{closure}()
#2 /path/vendor/predis/predis/src/Connection/StreamConnection.php(368): strval()
#3 /path/vendor/predis/predis/src/Connection/AbstractConnection.php(122): Predis\\Connection\\StreamConnection->writeRequest()
#4 /path/vendor/predis/predis/src/Client.php(381): Predis\\Connection\\AbstractConnection->executeCommand()
#5 /path/vendor/predis/predis/src/Client.php(335): Predis\\Client->executeCommand()
#6 /path/vendor/laravel/framework/src/Illuminate/Redis/Connections/Connection.php(116): Predis\\Client->__call()
#7 /path/vendor/laravel/framework/src/Illuminate/Redis/Connections/Connection.php(216): Illuminate\\Redis\\Connections\\Connection->command()
#8 /path/vendor/qruto/laravel-wave/src/Storage/BroadcastEventHistoryRedisStream.php(54): Illuminate\\Redis\\Connections\\Connection->__call()
#9 /path/vendor/qruto/laravel-wave/src/Sse/ServerSentEventStream.php(70): Qruto\\Wave\\Storage\\BroadcastEventHistoryRedisStream->pushEvent()
#10 /path/vendor/laravel/framework/src/Illuminate/Support/helpers.php(306): Qruto\\Wave\\Sse\\ServerSentEventStream->Qruto\\Wave\\Sse\\{closure}()
#11 /path/vendor/qruto/laravel-wave/src/Sse/ServerSentEventStream.php(67): tap()
#12 /path/vendor/symfony/http-foundation/StreamedResponse.php(92): Qruto\\Wave\\Sse\\ServerSentEventStream->Qruto\\Wave\\Sse\\{closure}()
#13 /path/vendor/symfony/http-foundation/Response.php(377): Symfony\\Component\\HttpFoundation\\StreamedResponse->sendContent()
#14 /path/public/index.php(67): Symfony\\Component\\HttpFoundation\\Response->send()
#15 /path/server.php(26): require_once('...')
#16 {main}

The order of xadd is not the same for phpredis and predis:
phpredis xadd:
https://github.com/phpredis/phpredis?tab=readme-ov-file#xadd
predis xadd:
https://github.com/predis/predis/blob/45b18eb2e06c7e1b3aaf98eb99e247ae0eb3ec0d/src/ClientInterface.php#L278

Possible fix for:

$id = $this->db->xAdd('broadcasted_events', '*', $eventData);

if($this->db instanceof PhpRedisConnection){
    $id = $this->db->xAdd('broadcasted_events', '*', $eventData);
}else{
    $id = $this->db->xAdd('broadcasted_events', $eventData, '*');
}

And xDel does not work with an empty array.

Possible fix for: https://github.com/qruto/laravel-wave/blob/d304c96b4a9326654fd5c6e42c7ce6243f147e52/src/Storage/BroadcastEventHistoryRedisStream.php#L65C9-L65C72

if(count($oldEvents) === 0){
    return;
}
$this->db->xDel('broadcasted_events', \array_keys($oldEvents));

How to reproduce the bug

  • Install the package as suggested in the README file.
  • Install predis (I used v2.2.2)
  • change laravel config database.redis.client to predis

Package Version

0.8.1

PHP Version

8.2.10

Laravel Version

v9.52.7

Which operating systems does with happen with?

Linux

Notes

No response

👍 processing on this.

Fixed in 0.8.2.

0.9.0 released with Laravel 11 support and artisan serve command adaptation.

Thank for notice and debugging information.