11

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?
Matt Warren
  • 10,279
  • 7
  • 48
  • 63
Arnold Zokas
  • 8,306
  • 6
  • 50
  • 76

1 Answers1

15

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();
    }
}
Arnold Zokas
  • 8,306
  • 6
  • 50
  • 76