Search code examples
rmongolite

Mongolite Error: Failed to read 4 bytes: socket error or timeout


I was trying to query a mongo database for all of the id's included in the database so I could compare the list to a separate data frame. However, when I attempt to find all sample_id fields I'm presented with:

Error: Failed to read 4 bytes: socket error or timeout

An example of the find query:

library(mongolite)
mongo <- mongo(collection,url = paste0("mongodb://", user,":",pass, "@", mongo_host, ":", port,"/",db))
mongo$find(fields = '{"sample_id":1,"_id":0}')
# Error: Failed to read 4 bytes: socket error or timeout

As the error indicates, this is probably due to some internal socket timeout problem due to the large amount of data. However, in the mongo documentation the default is set to never timeout.

socketTimeoutMS: The time in milliseconds to attempt a send or receive on a socket before the attempt times out. The default is never to timeout, though different drivers might vary. See the driver documentation.

So my question was why does this error occur when using mongolite? I think I've solved it but I'd welcome any additional information or input.


Solution

  • The simple answer is that, as indicated in the above quote from the mongo documenation, "different drivers might vary". In this case the default for mongolite is 5 minutes, found in this github issue, I'm guessing it's related to the C drivers.

    The default socket timeout for connections is 5 minutes. This means that if your MongoDB server dies or becomes unavailable it will take 5 minutes to detect this. You can change this by providing sockettimeoutms= in your connection URI.

    Also noted in the github issue is a solution which is to increase the sockettimeoutms in the URI. At the end of the connection URI you should add ?sockettimeoutms=1200000 as an option to increase the length of time (20 minutes in this case) before a socket timeout. Modifying the original example code:

    library(mongolite)
    mongo <- mongo(collection,url = paste0("mongodb://", user,":",pass, "@", mongo_host, ":", port,"/",db,"?sockettimeoutms=1200000"))
    mongo$find(fields = '{"sample_id":1,"_id":0}')