Predis is giving 'Error while reading line from server'
Asked Answered
P

6

27

I am using predis, it's subscribed to a channel and listening. It throws the following error (below) and dies after 60 secs exactly. It's surely not my web servers error or its timeout.

There is a similar issue being discussed here. Could not get much of it.

I tried setting connection_timeout in predis conf file to 0, but doesn't helps much.

Also if i keep using (send data to it and it processes) the worker it doesn't give any error. So its likely a timeout somewhere, and that too in connection.

Here is my code snippet, which is likely producing error, because if data is given to worker it runs this code and go forward, which produces no error after that.

$pubsub = $redis->pubSub();
$pubsub->subscribe($channel1);

foreach ($pubsub as $message) { //doing stuff here and unsubscribing from channel
}

Trace

PHP Fatal error:  Uncaught exception 'Predis\Network\ConnectionException' with message 'Error while reading line from the server' in Predis/Network/ConnectionBase.php:159 Stack trace:
#0 library/vendor/predis/lib/Predis/Network/StreamConnection.php(195): Predis\Network\ConnectionBase->onConnectionError('Error while rea...')
#1 library/vendor/predis/lib/Predis/PubSub/PubSubContext.php(259): Predis\Network\StreamConnection->read()
#2 library/vendor/predis/lib/Predis/PubSub/PubSubContext.php(206): Predis\PubSub\PubSubContext->getValue()
#3 pdf/file.php(16): Predis\PubSub\PubSubContext->current()
#4 {main}   thrown in Predis/Network/ConnectionBase.php on line 159

Checked the redis.conf timeout too, its also disabled.

Prospect answered 2/8, 2012 at 10:58 Comment(2)
can you connect to redis fine using redis-cli?Clatter
yes, also the worker is working fine if data is processed, if it is left for 60 sec, it dies and gives the errorProspect
P
45

Just set the read_write_timeout connection parameter to 0 or -1 to fix this. e.g.

$redis = new Predis\Client('tcp://10.0.0.1:6379'."?read_write_timeout=0");

Setting connection parameters is documented in the README. The author of Redis noted the relevance of the read_write_timeout parameter to this error in an issue on GitHub, in which he notes that:

If you are using Predis in a daemon-like script you should set read_write_timeout to -1 if you want to completely disable the timeout (this value works with older and newer versions of Predis). Also, remember that you must disable the default timeout of Redis by setting timeout = 0 in redis.conf or Redis will drop the connection of idle clients after 300 seconds of inactivity.

Prospect answered 13/8, 2012 at 9:39 Comment(5)
If you are using Laravel, add 'read_write_timeout' => -1 in Redis Database on config/database.phpLatimer
For heroku redis servers, you have to use the CLI: heroku redis:timeout [redis-app-name] --seconds 0 --app [parent-app-name]Tetter
Besides setting 'read_write_timeout' => -1 , run php artisan config:clear. For some reason, laravel was caching the configuration and this change wasn't taking effect.Uttica
@Latimer what key is it in config/database.php?Ganley
@Ganley on each redis server you have defined. I have this in ['redis']['default'] and another server I have .['redis']['another_server']Latimer
K
7

I had similar problem, better solution to the situation is not setting the timeout to 0 but using a exponential backoff and set the upper and the lower limit. Change in the config parameter connection_timeout to 0 will also solve the issue.

Knudsen answered 4/9, 2012 at 20:7 Comment(0)
A
1

I got the resolution to the problem. So, there is a limit to ports that a application server can connect to a particular application on another machine. These ports were getting exhausted. We increased the limit and the problem got resolved.

How we got to know about this problem ? In php, we were getting "Cannot assign requested address" error while creating a socket (error code 99).

Accalia answered 7/6, 2018 at 12:3 Comment(0)
S
1

At /etc/redis/redis.conf , set

timeout = 0 
Salto answered 25/9, 2020 at 15:22 Comment(0)
C
0

I'm using Heroku and solved this problem with switching from Redis Heroku to Redis Enterprise addon and then:

use Predis\Client as PredisClient;

To solve collision with GuzzleHttp\Client. You can leave the

as PredisClient

line if you are not usng GuzzleHttp.

And then connection:

$redisClient = new PredisClient(array(
     'host' => parse_url(env('REDIS_URL'), PHP_URL_HOST),
     'port' => parse_url(env('REDIS_URL'), PHP_URL_PORT),
     'password' => parse_url(env('REDIS_URL'), PHP_URL_PASS)
)

);

(You can find your 'REDIS_URL' automatically prefilled in Heroku config vars).

Croft answered 9/12, 2021 at 10:40 Comment(0)
E
0

if you used Laravel sail and now want to use artisan serve ,you should go to your .env file and change REDIS_HOST from Redis to 127.0.0.1

Ezmeralda answered 21/7, 2023 at 9:35 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.