-
Notifications
You must be signed in to change notification settings - Fork 16
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
R crash on Redis server loss #20
Comments
Not sure how much I really care. Redis is a generally always up quality and when it is down access from R may be the least worry. Pull requests welcome. I am unlikely to do this myself. |
I might take this one on; I'm loathe to see an entire R session crash because of an intermittent network error. But, I suppose if I did take it on we should also add some of the benchmarking code to the testing framework - just to be sure that none of the changes result in a notable performance hit. |
Easy -- prefix each user-space command with a ping :) We would at least one line to each function emitting a request to Redis. Worth it? |
Well, the ping will tell you that it is up at the time of the ping, but not that it was actually up/connected correctly at the time of your request. It also adds an additional round-trip to any transaction. Clearly NVG. Instead, I was thinking instead of wrapping redisCommand and redisCommandArgv with a safety check that a NULL wasn't received as the reply. It would mean refactoring the code to use the NULL safe versions of those functions. I quickly banged out the following:
It seems to pass tests and survives the described example. What I don't know is if it would recover from a transitory loss of the connection. I haven't played around with toxiproxy yet, maybe @richfitz could do so and let us know if this solution saves us from anything other than the test example. |
Nice. I had the same idea but was in a rush and didn't see / remember |
I stupidly have been making my edits to RcppRedis on my master branch. Once we've resolved the pending pull request, then I'll submit this one for consideration. |
Replicated the test as described here https://github.com/richfitz/toxiproxyr. Confirmed that the proposed code works under that case as well. |
We've all been there. Maybe save the files by hand and do a |
@eddelbuettel You can probably close this issue. |
Just to be plain: because your PR addressed it? |
I actually was able to experience this one in the wild while torturing a Redis server. The modifications ended up working as expected. Though, it got me wondering about whether trying to automatically rebuild the connection at least once would make sense before restoring to throwing an error. |
One could. But then: try once? Twice? N+1 times? At some point you gotta error out. |
True, and I kind of suspect that retrying the connection wouldn't have solved anything in the case I experienced; although it might protect users who incorrectly use a fork of the connection argument. In the latter vein, I was thinking of defaulting to one attempt after a 1 second delay, but perhaps adding yet another configurable parameter to init. EDIT: Actually a hard limit of 1 would be easiest. Promising more than one would require thinking carefully about how to handle errors when making the initial connection / writing out separate reconnection code. |
I can live with trying once. The server may just be away 'temporarily' (even for an upgrade). It would be a nice to have, but I don't think it is a priority. (In general the edge-case handling in RcppRedis is of course rudimentary. We make day. "One day" @richfitz will gift us a real package on CRAN and then we all switch anyway :) Until then, hack mode...) |
In addition to not being on CRAN one of my reservations about redux was not knowing how it would do in speed compared to RcppRedis especially on serialization/deserialization; for some reason I ended up with the misconception that was happening using methods similar to rredis. At any rate, I was pleasantly surprised, redux compares favorably to RcppRedis. |
Nice benchmarks! And thumbs up for empirics. I only glanced (about to head out) but you also included serialization cost, right? |
I believe I did account for the serialization costs, but I always welcome peer review. |
I'm sorry that this comment is off-topic from the original issue posting. Note that the first example serializes the object 1000 times in the But to be fair I don't think that matters too much. I was a bit surprised test replications elapsed relative
1 hiredis() 1000 0.110 1.000
2 rredis() 1000 0.281 2.555 for the file adapted from http://rpubs.com/rpierce/simpleBenchmarkRedux (and slightly faster yet if you uncomment the pipelining lines): library(RcppRedis)
library(rredis)
library(rbenchmark)
data(trees)
fit <- lm(log(Volume) ~ log(Girth) + log(Height), data=trees)
redis <- new(Redis)
hiredis <- function() redis$set("fits", fit)
rredis <- function() redisSet("fits2", fit)
redisConnect()
#redisSetPipeline(TRUE)
res <- benchmark(hiredis(), rredis(), replications=1000)[,1:4]
#redisSetPipeline(FALSE)
print(res) The rest of the ~ 2x difference with RcppRedis is not easy however. Much of it is in tryCatch for things like interrupts of transfers (important in many real-world settings), other problems (too large of payloads), etc. Again, sorry for the diversion. On 12/11/15, drknexus notifications@github.com wrote:
|
A welcome diversion; I'm not sure there is a good forum functionality in which we could have discussed this otherwise. @bwlewis Are you sure the first example serializes the object 1000 times in the hiredis and rredis loops, but only once in the redux benchmark loop? I'm not seeing it. The difference is that both rredis and RcppRedis implicitly do the serialization whereas with redux you have to manually handle it to coerce the input to $SET. Regardless, I'm thrilled to hear that you found some places for performance enhancement in rredis. |
Closing per request earlier in this issue. |
Minimal, contrived, example:
will crash R with
Seen on various flavours of OSX and Linux. The gdb backtrace is:
A fix would be to add something like:
after every
redisCommand
/redisCommandArgv
in src/Redis.cppWhile the above is through Redis server shutdown the same thing happens if the connection is lost (e.g. client and server on different machines on different hosts and a loss of the link between). I have confirmed this with toxiproxy.
The text was updated successfully, but these errors were encountered: