Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Exception thrown in blPop() #99

Closed
arctica opened this issue Dec 9, 2011 · 9 comments
Closed

Exception thrown in blPop() #99

arctica opened this issue Dec 9, 2011 · 9 comments

Comments

@arctica
Copy link

arctica commented Dec 9, 2011

I'm getting an exception "read error on connection" when trying to do a blocking LPOP on a list (list doesn't exist actually).

The code is pretty simple

$res = $redis->blPop('daemon_http_import:todo', 30);

It takes about 3-4 seconds and the exception is thrown. Other commands seem to work fine.
Here some strace output:

sendto(5, "*3\r\n$5\r\nBLPOP\r\n$23\r\ndaemon_http_"..., 54, MSG_DONTWAIT, NULL, 0) = 54
poll([{fd=5, events=POLLIN|POLLPRI|POLLERR|POLLHUP}], 1, 0) = 0 (Timeout)
poll([{fd=5, events=POLLIN|POLLERR|POLLHUP}], 1, 3500) = 0 (Timeout)
close(5)                                = 0
write(2, "Exception: /scripts/daemon_http_"..., 67Exception: /scripts/daemon_http_import:37 read error 
on connection
) = 67

No idea why it throws the exception and then even closes the connection to redis.
I tried other timeout values but it's always the same. As seen on the strace output, it doesn't even wait long enough for the timeout to expire.

@nicolasff
Copy link
Member

Thank you for reporting this, I'll have a look this week-end.

@ghost
Copy link

ghost commented Jan 9, 2012

Same or similar problem on empty or not existent lists:

sendto(3, "*3\r\n$5\r\nBLPOP\r\n$28\r\nqueue_attr_d"..., 64, MSG_DONTWAIT, NULL, 0) = 64
poll([{fd=3, events=POLLIN|POLLPRI|POLLERR|POLLHUP}], 1, 0) = 0 (Timeout)
poll([{fd=3, events=POLLIN|POLLERR|POLLHUP}], 1, 2000) = 0 (Timeout)
close(3)                                = 0
--- SIGSEGV (Segmentation fault) @ 0 (0) ---
+++ killed by SIGSEGV +++
Segmentation fault
bash-4.2# php -v
PHP 5.3.8-1+b1 with Suhosin-Patch (cli) (built: Nov 13 2011 11:15:06)
Copyright (c) 1997-2011 The PHP Group
Zend Engine v2.3.0, Copyright (c) 1998-2011 Zend Technologies
    with XCache v1.3.2, Copyright (c) 2005-2011, by mOo
    with Suhosin v0.9.32.1, Copyright (c) 2007-2010, by SektionEins GmbH
bash-4.2# redis-server -v
Redis server version 2.4.5 (00000000:0)

@ihsw ihsw mentioned this issue Feb 8, 2012
@colinmollenhour
Copy link

When I tested this with a 10 second timeout I got a "read error on connection" in ~2.5 seconds. I am not using pconnect. When I test it with a Credis_Client (standalone php) it fails the 60 second test (works up to 50 seconds). The server timeout is set to 300 seconds. It seems phpredis does not handle blocking or long-running calls correctly in general.

@hobbs136
Copy link

set default_socket_timeout=-1 in php.ini and set parameter timeout=3 when connecting and be sure that your timeout in config of redis server is zero, then the problem will be fixed

@colinmollenhour
Copy link

Indeed, the default_socket_timeout is 60 seconds on my system. However, it would be best for this timeout to be set at runtime by the Redis driver.

@nicolasff
Copy link
Member

Although it would indeed solve the problem in this particular case, it is not the library's role to silently override system-wide settings for which the admin is responsible.

@colinmollenhour
Copy link

Sockets can be used for so many things though.. You may want a 60 second timeout when connecting to an API service, but a 20 minute timeout when connecting to Redis for a blocking or pub/sub operation. Perhaps this should be added as an additional parameter/method so the programmer can make this decision and not the admin?

@michael-grunder
Copy link
Member

I ran a few tests and I think this is what's happening:

  • If you connect with no timeout (timeout = 0), it uses the default_socket_timeout value from php.ini
  • If you connect with a nonzero timeout, it will block up to that long. The timeout parameter in BLPOP is just passed as an argument to Redis

In theory, the socket timeout value could be updated with the value passed into BLPOP which would override whatever connect timeout was called (or default_socket_timeout if none was used), but I don't know if that is a proper solution or not.

atdt pushed a commit to wikimedia/mediawiki that referenced this issue May 5, 2014
* The value is also configurable just like connectTimeout
* This deals with problems like phpredis/phpredis#99
  and phpredis/phpredis#70

Change-Id: I05e91e05764020854d04673b7decae30359f57e9
@lilien1010
Copy link

try{
$val = $redis->blPop(REDIS_LIST_KEY,'', 60);
}
catch(Exception $e){echo ( $e->getMessage()).time()."\r\n"; continue;
}
//example code like this, I got the exception every 3 second and no matter what is timeout values,
// changed php.ini default_socket_timeout=-1 and default_socket_timeout=0, the same

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants