Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How should stale indexes be handled during testing?

I am using RavenDB in In-Memory mode for unit testing. My queries are backed by static indexes. I am not using WaitForNonStaleResults() API (nor do I want to).

Typical workflow for a test is:

  1. Initialise RavenDB in In-Memory mode
  2. Integrate indexes using IndexCreation.CreateIndexes(Assembly, IDocumentStore)
  3. Insert test data (for verifying query behaviour)
  4. Run query
  5. Verify query output

I have noticed steps 1-3 happen so quickly, that static indexes don't have time to get updated before step 4 - therefore the indexes are stale.

I have created a quick work-around for this. After step 3, I execute:

while (documentStore.DocumentDatabase.Statistics.StaleIndexes.Length != 0)
    Thread.Sleep(10);

This feels cumbersome. What I would like to know is:

  • Is it normal for indexes to be stale when running RavenDB in In-Memory mode?
  • Is there a better way to avoid stale indexes during testing?
like image 450
Arnold Zokas Avatar asked Jan 30 '12 03:01

Arnold Zokas


1 Answers

Cross-posted this to RavenDB usergroup and have a working solution.

Is it normal for indexes to be stale when running RavenDB in In-Memory mode?

Yes. An index is an index.

Is there a better way to avoid stale indexes during testing?

Yes. Configure global conventions when initialising document store:

var store = new EmbeddableDocumentStore();
store.RunInMemory = true;
store.Conventions = new DocumentConvention
{
    DefaultQueryingConsistency = ConsistencyOptions.QueryYourWrites
};

store.Initialize();

Note: ConsistencyOptions.QueryYourWrites doesn't work with Map/Reduce indexes, i.e. indexes with a Reduce => ... section. For these you have to use Customize(x => x.WaitForNonStale...()) when querying

Update: There is another approach, which may be better (haven't personally tried it yet). You could implement IDocumentQueryListener to force all queries to return non-stale results:

var store = new EmbeddableDocumentStore { RunInMemory = true };
store.Initialize();

store.RegisterListener(new ForceNonStaleQueryListener());

public class ForceNonStaleQueryListener : IDocumentQueryListener
{
    public void BeforeQueryExecuted(IDocumentQueryCustomization customization)
    {
        queryCustomization.WaitForNonStaleResults();
    }
}
like image 69
Arnold Zokas Avatar answered Nov 01 '22 13:11

Arnold Zokas