Following the directions here http://tugdualgrall.blogspot.com/2012/12/couchbase-101-create-views-mapreduce.html I have set up some code that pulls a list of IDs from the cache by creaing a view on the fly the first time if it doesn't exist. The problem is that the first time the view is created one or both of two undesirable behaviors are usually occurring;
1) Error "Failed to access the view" is thrown
2) 0 results are returned the first time
What do I need to do in order to ensure that the view is fully created and ready to return correct results before I use it? I am calling CouchbaseClient.createDesignDoc(DesignDoc) which internally calls return asyncCreateDesignDoc(doc).get(); I would expect the .get() to block until the view was fully created. I understand that it may take a few seconds for the view to fully index itself, but I am ok with waiting. It is more important to the application that it get results and this is only going to be a one-time process the first time the user runs my Couchbase connector.
The create document, as you said, execute the call to create the view but does not block, or check that the view is created, also once the view is created, you have to let the system do the indexing of the document.
First of all, this API has not been build to create "view on the fly" to mimic adhoc queries (because of the behavior describe above) but mainly to be able to deploy views automatically when you deploy an application or new version of the application.
That said it is possible to work around this with simple code:
- when you create the view, the "createDesignDoc()" method, you can check just after if the view is created in your code and "loop/wait" until it is created. (until the "Failed to access the view" exception is not thrown anymore - check that you do not end with an infinite loop in case of real exception)
- once the view is created, the server needs to index "all" existing documents this takes some time depending of the size of your dataset. This is why your view does not return anything first. So when you query you index just be sure you do a stale=false like that the index will be updated before returning the result to your application. Note that with stale, you application will have to way.
Hope that helps!
Thanks for the clarification. I just wanted to make sure I wasn't missing anything.
I got pretty good success by writing a chunk of code that would loop up to 5 times. It would try to create the view and execute it with non-stale data. If something errored, it would sleep for 1000 ms and try again. There's a few-second delay the first time through, but it comes back with data which is exactly what I needed.
As simple as that is, it would be nice to see it built into the Java SDK for scenarios where people create a view on the fly and need to use it immediately.