-
Notifications
You must be signed in to change notification settings - Fork 354
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
[FEATURE] Flexibility to set socket_timeout for each request to redis #307
Comments
First of all, how can you tell if a redis instance is going down? If it's already down, socket_timeout won't help. Since it will fail to reconnect to Redis, and won't send any command to it.
First of all, it's not a good idea to run a long running command with Redis, since it's single-threaded, and the long running command will block Redis. If you do need to do that, I think you'd better use a dedicated Redis object to do the job. Because
If this feature is added, the API might change a lot. I'm not sure if this is a good idea. So I'll keep this issue open, but hold this request for now. If there're many others need this feature, I'll reconsider it. Anyway, thanks for your proposal! Regards Regards |
Hi @sewenew, I am handling data from sensors that deliver their data at pre-defined intervals. Eg. sensor A, @ a 3 second interval, sensor B @ a 15 second interval, etc. My orchestration of the handling of the data, is data-triggered. This means I need to know if a sensor stopped delivering data. If so, I need to trigger the data handling in any case, marking the data as invalid. At the moment, I have a C++ process with a thread per sensor. In order not to use a Redis instance per thread, I use a reduced socket_timeout and only handle the data under special conditions, when a timeout occurs. sw::redis::ConnectionOptions connectionOptions;
connectionOptions.socket_timeout = std::chrono::seconds(4);
sw::redis::Redis redis(connectionOptions);
std::thread a(processValue(std::ref(redis), "A", std::chrono::seconds(3), std::ref(connectionOptions.socket_timeout)));
std::thread b(processValue(std::ref(redis), "B", std::chrono::seconds(15), std::ref(connectionOptions.socket_timeout)));
void processValue(sw::redis::Redis& redis,
const std::string& key,
const std::chrono::seconds& interval,
const std::chrono::seconds& timeout)
{
auto sub = redisInstance.subscriber();
sub.on_message([](std::string key, std::string val) {doCalc(key, val, true);});
sub.subscribe(key);
sub.consume();
std::chrono::seconds subTimeWithoutData(0);
while (running) {
try {
sub.consume();
subTimeWithoutData = std::chrono::seconds(0);
}
catch (const sw::redis::TimeoutError &e) {
subTimeWithoutData = subTimeWithoutData + timeout;
if (subTimeWithoutData > interval) {
// Reduce the subTimeWithoutData accordingly.
subTimeWithoutData = subTimeWithoutData - interval;
// Do the calc with invalid data.
doCalc(key, dummyVal, false);
}
}
}
sub.unsubscribe(key);
sub.consume();
} Having a (p)subscribe or a consume method that takes a timeout value, would simplify the implementation of the above use-case enormously. BTW, I cannot think of any non-pub/sub kind of commands that would benefit from custom timeouts, as in the real world all non-pub/sub commands should be super fast with their response, otherwise something is wrong in any case. Regards |
Hi @sewenew and @quoctuanuit, @quoctuanuit wrote:
Like @sewenew said, you might have a design problem. @sewenew wrote:
Dead Redis nodes can be determined independently, by subscribing to specific keys of a Sentinel server. Regards |
In this case, you CAN have a
Regards |
Yes, you can be notified by Sentinel, but only when the node is already down. However, if I understood correctly, I think @quoctuanuit want to modify the timeout before the node is down, i.e. the node is still alive, but is going to be down. Correct me if I misunderstand his question, since I'm not a native speaker :) Regards |
Hi @sewenew,
Thanks for your explanation and your example. sw::redis::Redis redis(connectionOptions); // <------ since no command is sent with Redis object, no connection will be created. Would it be possible to mention this example in the documentation, or maybe even enhance the documentation with an example like this? BTW, this information could also have been helpful for #240. Regards |
Hi @sewenew,
I read @quoctuanuit's explanation again and I see your point. One could read it the way you explained. So, in this case something that will bring a node down, will tell his application to reduce the timeout, so that the app can know almost immediately when things are not working any more. I however think he basically wants a very short timeout so that he can know that something is wrong, as soon as a node is down or not responding any more. I don't know of a way to automatically detect if a node is on its way down (not down, but will be down soon). Maybe @quoctuanuit should try to explain this to us, if it is still relevant. Anyway, I think that his real issue was to be able to set the socket_timeout to some value, before any redis call:
This is indeed not possible at the moment. However, after reading the example that you posted a few moments ago, I really see no use-case for being able to adjust the socket_timeout before every redis call. Regards |
Hi @wingunder Thanks for your suggestion! I've updated the doc, and you can take a look: commit . Regards |
Hi @sewenew,
You're welcome. Thanks for adding this to the documentation. Regards |
Hi @sewenew @wingunder ! One more benefit of setting socket_timeout per request is that application can control what command should be blocked until server replied, or should we have some timeout for it.
Well, I believe that it's not single-threaded, e.g every blocking module command is handled by it's own thread in redis. |
In this case, so far, I'd suggest that you create different Regards |
Hi @sewenew
I'm using RedisCluster and running into the situation that different socket_timeout values for each request are needed:
The socket_timeout value will be decided by application. However, it looks like that we can not adjust the socket_timeout for each redis request for now.
It would be great that we can support this feature. How do you think?
The text was updated successfully, but these errors were encountered: