-
Notifications
You must be signed in to change notification settings - Fork 1.8k
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
Add timeout support for libuv adapter #1016
Conversation
Thanks, looks good on first glance. I know it's somewhat trivial but would you mind re-indenting with 4 spaces? Then I'll get it merged. |
@michael-grunder |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Indentation looks fine. Didn't review the actual code. 🙈
Hi, this code asserts when testing against the #include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <signal.h>
#include <hiredis.h>
#include <async.h>
#include <adapters/libuv.h>
#include <time.h>
#include <sys/time.h>
void sleepCb(redisAsyncContext *c, void *r, void *privdata) {
printf("sleep CB\n");
}
int main (int argc, char **argv) {
#ifndef _WIN32
signal(SIGPIPE, SIG_IGN);
#endif
uv_loop_t* loop = uv_default_loop();
redisAsyncContext *c = redisAsyncConnect("127.0.0.1", 6379);
if (c->err) {
/* Let *c leak for now... */
printf("Error: %s\n", c->errstr);
return 1;
}
redisLibuvAttach(c,loop);
redisAsyncSetTimeout(c, (struct timeval){ .tv_sec = 1, .tv_usec = 0});
redisAsyncCommand(c, sleepCb, NULL, "DEBUG SLEEP %f", 1.5);
uv_run(loop, UV_RUN_DEFAULT);
return 0;
}
I'm wondering why we need the sentinel value at all edit: I took a shot at adding a timeout to the libuv adapter and came up with this. |
@michael-grunder
I don't know if it is ok to just stop the timer and not 'destroy' it, but it should be good. |
@michael-grunder BTW, It is necessary to call |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice, I have some suggestions.
Makefile
Outdated
@@ -166,6 +166,8 @@ hiredis-example-macosx: examples/example-macosx.c adapters/macosx.h $(STLIBNAME) | |||
hiredis-example-ssl: examples/example-ssl.c $(STLIBNAME) $(SSL_STLIBNAME) | |||
$(CC) -o examples/$@ $(REAL_CFLAGS) -I. $< $(STLIBNAME) $(SSL_STLIBNAME) $(REAL_LDFLAGS) $(SSL_LDFLAGS) | |||
|
|||
hiredis-example-uvtm: examples/example-uvtm.c adapters/libuv.h $(STLIBNAME) $(SSL_STLIBNAME) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We already have an example for libuv some rows below. It might be better to put this new rule close to the existing one?
A suggestion is to rename this new example to something like hiredis-example-libuv-timeout
to match the existing naming.
Maybe the existing one can be used for the timeout case?
examples/example-uvtm.c
Outdated
#include <sys/time.h> | ||
|
||
void sleepCb(redisAsyncContext *c, void *r, void *privdata) { | ||
printf("sleep CB\n"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When the async command timeout the reply should be NULL
. This can be shown in this example by using
redisReply *reply = r;
assert(reply == NULL);
or by some simple printf.
examples/example-uvtm.c
Outdated
@@ -0,0 +1,42 @@ | |||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We have an existing example-libuv.c
, rename this to something like example-libuv-timeout.c
?
Makefile
Outdated
@@ -166,6 +166,8 @@ hiredis-example-macosx: examples/example-macosx.c adapters/macosx.h $(STLIBNAME) | |||
hiredis-example-ssl: examples/example-ssl.c $(STLIBNAME) $(SSL_STLIBNAME) | |||
$(CC) -o examples/$@ $(REAL_CFLAGS) -I. $< $(STLIBNAME) $(SSL_STLIBNAME) $(REAL_LDFLAGS) $(SSL_LDFLAGS) | |||
|
|||
hiredis-example-uvtm: examples/example-uvtm.c adapters/libuv.h $(STLIBNAME) $(SSL_STLIBNAME) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add the example to the CMakeLists.txt
in examples/
folder as well.
See how example-libuv
is added and add a ADD_EXECUTABLE
and TARGET_LINK_LIBRARIES
to the new example.
examples/example-uvtm.c
Outdated
printf("sleep CB\n"); | ||
} | ||
|
||
int main (int argc, char **argv) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
warning: unused parameter argc
and argv
examples/example-uvtm.c
Outdated
#include <time.h> | ||
#include <sys/time.h> | ||
|
||
void sleepCb(redisAsyncContext *c, void *r, void *privdata) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
warning: unused parameter c
, r
, privdata
5dc9c81
to
351c1cf
Compare
push -f to fix commit message, sorry |
adapters/libuv.h
Outdated
} | ||
// updates the timeout if the timer has already started | ||
// or start the timer | ||
uv_timer_start(&p->timer, (uv_timer_cb)redisLibuvTimeout, millsec, 0); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Casting a function pointer in this way is undefined behavior and may crash in weird and hard to track down ways.
I'm not overly familiar with libuv but I'm guessing there is a way to #ifdef
around it?
Edit: Looks like we can either use UV_VERSION
at compile-time, or even uv_version()
at runtime and then create a wrapper function with the int
parameter that calls our real one without.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done, it turns out I was using a very old libuv version (0.10.x), however I added the #ifdef
and it is ok now.
Co-authored-by: Michael Grunder <michael.grunder@gmail.com>
adapters/libuv.h
Outdated
#if UV_MAJOR_VERSION > 0 || UV_MINOR_VERSION > 11 || (defined(UV_VERSION_PATCH) && UV_VERSION_PATCH > 22) | ||
#if !defined(UV_VERSION_PATCH) || (UV_MAJOR_VERSION < 1 && UV_MINOR_VERSION < 12 && UV_VERSION_PATCH < 23) | ||
// libuv removed `status` parameter since v0.11.23 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is maybe wrong for versions like 0.10.37 (it exists).
minor < 12 doesn't always mean minor == 11.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, thanks for the note, you are correct, major.minor.patch < 0.11.23
expands to something like major < 0 || (major == 0 && minor < 11) || (minor == 11 && patch < 23)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let me try reduce it, could you lend some help?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Major < 0 can't happen so this part can be removed.
I think major == 0 && (minor < 11 || (minor == 11 && patch < 23))
Fixed a silly typo, corrected version check macro, thanks @zuiderkwast for the help |
Co-authored-by: Viktor Söderqvist <viktor@zuiderkwast.se>
Merged, thanks! |
see #1015
sorry for no test cases : (