After an awesome conversation with a RavenDB employee at Twin Cities Code Camp, I wanted to add a quick follow up to my eventual consistency blog post.
I illustrated the issue that eventual consistency can cause in certain user interfaces. Because I was trying to remain platform agnostic in my code camp talk, I didn’t point out a feature of RavenDB that helps a lot (and that we use a at work often enough).
RavenQueryStatistics stats; var lists = session.Query<ToDoList>() .Statistics(out stats) .Where(x => x.Name == "Maggie") .Customize(x => x.WaitForNonStaleResults(TimeSpan.FromSeconds(5))) .ToList();
As you can see, it’s possible to ask raven to wait for non-stale results on a query.
This can solve the UI problem I illustrated. It was omitted from my talk yesterday because I was trying to avoid giving a pure Raven talk, but I think it belongs here :-).
I will give this a caveat, which is that I’ve seen some LONG index build times in Raven before. I don’t jump to this solution because the timeout puts us in a situation where no data may be returned. In the eventual consistency philosophy of ‘better stale than none’, I’d rather rework my UI to better handle eventual consistency.
Maggie – great to see other RavenDB users blogging about what I consider one of the most advanced JSON based document stores available. Regarding your eventual consistency example, another pattern that we have leveraged often is to do the query with WaitForNonStaleResultsAsOfLastWrite at the time of SAVE along with a try/catch. Most users expect a save operation (in your example, saving the new task) to have a bit of a lag (take a second or two). So, having the save operation not return until the index has been updated has been a better approach for us then putting the wait in the retrieve (since we like these fast!). If there is an issue and the index is not updated within a timeout period of say 3 seconds – you can just return from the save with a flag to hint your UI to the potential consistency issue. Your UI still has to be mindful of potential concurrency issues, but the vast majority of the time this solution will solve the challenges while still allowing you to do fetches without try/catches.
LikeLike