2012-04-25 22 views
22

जब यूनिट परीक्षण RavenDb के साथ परीक्षण करते हैं, तो अक्सर यह मामला होता है कि नया जोड़ा गया डेटा पुनर्प्राप्त या अन्यथा संसाधित किया जाता है। इससे 'स्टेल इंडेक्स' अपवाद हो सकते हैं उदा।रावेनडीबी: यूनिट परीक्षण

Bulk operation cancelled because the index is stale and allowStale is false 

अपनी अनुक्रमणिका तक इंतजार के लिए जवाब

तरह से डेटाबेस के लिए मजबूर करने (IDocumentStore उदाहरण) के एक नंबर के अनुसार प्रसंस्करण से पहले पुरानी नहीं हैं एक प्रश्न या बैच आपरेशन IDocumentStore initialisation के दौरान DefaultQueryingConsistency = ConsistencyOptions.QueryYourWrites उपयोग करने के लिए, इस तरह है:

public class InMemoryRavenSessionProvider : IRavenSessionProvider 
{ 
    private static IDocumentStore documentStore; 

    public static IDocumentStore DocumentStore 
    { 
     get { return (documentStore ?? (documentStore = CreateDocumentStore())); } 
    } 

    private static IDocumentStore CreateDocumentStore() 
    { 
     var store = new EmbeddableDocumentStore 
     { 
      RunInMemory = true, 
      Conventions = new DocumentConvention 
      { 
       DefaultQueryingConsistency = ConsistencyOptions.QueryYourWrites, 
       IdentityPartsSeparator = "-" 
      } 
     }; 
     store.Initialize(); 
     IndexCreation.CreateIndexes(typeof (RavenIndexes).Assembly, store); 
     return store; 
    } 

    public IDocumentSession GetSession() 
    { 
     return DocumentStore.OpenSession(); 
    } 
} 

दुर्भाग्य से, कोड से काम नहीं होता। मुझे अभी भी स्टेल इंडेक्स के बारे में अपवाद मिल रहे हैं। इन्हें डमी प्रश्नों में डालकर हल किया जा सकता है जिसमें .Customize(x => x.WaitForNonStaleResultsAsOfLastWrite()) शामिल है।

यह ठीक है, जब तक कि इन्हें यूनिट टेस्ट में शामिल किया जा सके, लेकिन यदि वे नहीं कर सकते हैं तो क्या होगा? मुझे लगता है कि ये WaitForNonStaleResults* कॉल उत्पादन कोड में रेंग रहे हैं इसलिए मैं पास करने के लिए यूनिट-टेस्ट प्राप्त कर सकता हूं।

तो, क्या रेवेनडीबी के नवीनतम संस्करण का उपयोग करके, निश्चित रूप से यूनिट परीक्षण के उद्देश्यों के लिए - इंडेक्स को संसाधित करने की अनुमति देने से पहले ताज़ा करने के लिए मजबूर करने के लिए एक निश्चित अग्नि तरीका है?

संपादित करें 1

यहाँ एक समाधान उत्तर के आधार पर देने के लिए नीचे दिए गए है कि एक प्रतीक्षा मजबूर करता जब तक सूचकांक बासी नहीं है। मैंने यूनिट-परीक्षण सुविधा के लिए इसे एक विस्तार विधि के रूप में लिखा है;

public static class IDocumentSessionExt 
{ 
    public static void ClearStaleIndexes(this IDocumentSession db) 
    { 
     while (db.Advanced.DatabaseCommands.GetStatistics().StaleIndexes.Length != 0) 
     { 
      Thread.Sleep(10); 
     } 
    } 
} 

और यहाँ एक यूनिट टेस्ट कि वर्बोज़ WaitForNonStaleResultsAsOfLastWrite तकनीक का उपयोग किया गया था, लेकिन अब neater विस्तार विधि का उपयोग करता।

[Fact] 
public void Should_return_list_of_Relationships_for_given_mentor() 
{ 
    using (var db = Fake.Db()) 
    { 
     var mentorId = Fake.Mentor(db).Id; 
     Fake.Relationship(db, mentorId, Fake.Mentee(db).Id); 
     Fake.Relationship(db, mentorId, Fake.Mentee(db).Id); 
     Fake.Relationship(db, Fake.Mentor(db).Id, Fake.Mentee(db).Id); 

     //db.Query<Relationship>() 
     // .Customize(x => x.WaitForNonStaleResultsAsOfLastWrite()) 
     // .Count() 
     // .ShouldBe(3); 

     db.ClearStaleIndexes(); 
     db.Query<Relationship>().Count().ShouldBe(3); 
     MentorService.GetRelationships(db, mentorId).Count.ShouldBe(2); 
    } 
} 
+1

यह अब DocumentStore बजाय DocumentSession के खिलाफ आयोजित है, इसलिए विस्तार विधि db.Advanced.DocumentStore.DatabaseCommands की तरह कुछ का उपयोग करने के बदल जाएगा। GetStatistics()। StaleIndexes.Any(), या अगर आप – adrian

उत्तर

27

आप एक नक्शा है, तो/सूचकांक में कमी, DefaultQueryingConsistency = ConsistencyOptions.QueryYourWrites काम नहीं करेगा। आपको एक वैकल्पिक विधि का उपयोग करने की आवश्यकता है।

अपने इकाइयों में परीक्षण, इस तरह कॉल कोड, सीधे के बाद आप किसी भी डेटा सम्मिलित किया है, यह अद्यतन करने के लिए सभी अनुक्रमित मजबूर इससे पहले कि आप कुछ और करना होगा:

while (documentStore.DatabaseCommands.GetStatistics().StaleIndexes.Length != 0) 
{ 
    Thread.Sleep(10); 
} 

अद्यतन आप निश्चित रूप से यह एक विस्तार विधि में डाल सकता है, अगर आप चाहते हैं:

public static class IDocumentSessionExt 
{ 
    public static void ClearStaleIndexes(this IDocumentSession db) 
    { 
     while (db.Advanced.DatabaseCommands.GetStatistics().StaleIndexes.Length != 0) 
     { 
      Thread.Sleep(10); 
     } 
    } 
} 

तो फिर तुम कह सकते हैं:

db.ClearStaleIndexes(); 
+0

कर सकते हैं तो सीधे दस्तावेज़स्टोर को हाथ से रखें, मैं 'थ्रेड स्लीप (10)' विचार का प्रयास करूंगा। हालांकि मेरे पास मैप इंडेक्स हैं (उनके पास नक्शा फ़ंक्शन है लेकिन कम फ़ंक्शन नहीं है) और यह ये इंडेक्स है जो 'थोक ऑपरेशन .. इंडेक्स स्टेल' अपवाद फेंक रहे हैं। क्या 'ConsistencyOptions.QueryYourWrites' को मानचित्र-केवल अनुक्रमणिका के लिए काम करने की उम्मीद है? – biofractal

+0

ऐसा करना चाहिए, लेकिन थोक ऑपरेशन समस्या हो सकती है। यह सुनिश्चित करने के लिए उपर्युक्त कोड का उपयोग करें कि सभी अनुक्रमणिका अद्यतित हैं (दस्तावेज़ डालने के बाद और पूछताछ से पहले) और आपको ठीक होना चाहिए। –

+1

कृपया संपादित करें देखें 1. यह एक इलाज करता है, हालांकि आप अपने उत्तर को नवीनतम वाक्यविन्यास में अपडेट करना चाहते हैं। एक विस्तार विधि के रूप में प्रतीक्षा को समाहित करना सबकुछ अच्छा और साफ बनाता है :-) – biofractal

14

आप वास्तव में गैर-मूल परिणामों की प्रतीक्षा करने के लिए दस्तावेज़स्टोर पर एक क्वेरी श्रोता जोड़ सकते हैं।इसका उपयोग यूनिट परीक्षणों के लिए किया जा सकता है क्योंकि यह दस्तावेज़ स्टोर पर है और प्रत्येक ऑपरेशन नहीं है।

// Initialise the Store. 
var documentStore = new EmbeddableDocumentStore 
       { 
        RunInMemory = true 
       }; 
documentStore.Initialize(); 

// Force queries to wait for indexes to catch up. Unit Testing only :P 
documentStore.RegisterListener(new NoStaleQueriesListener()); 

.... 


#region Nested type: NoStaleQueriesListener 

public class NoStaleQueriesListener : IDocumentQueryListener 
{ 
    #region Implementation of IDocumentQueryListener 

    public void BeforeQueryExecuted(IDocumentQueryCustomization queryCustomization) 
    { 
     queryCustomization.WaitForNonStaleResults(); 
    } 

    #endregion 
} 

#endregion 

(बेशर्मी RavenDB how to flush? से चोरी)

+2

मैंने इसे आजमाया और यह सामान्य 'क्वेरी <>()' कॉल (कोई स्टेल इंडेक्स) के लिए काम नहीं किया, लेकिन यह 'डीबी' के माध्यम से एक मैप इंडेक्स (कोई कमी नहीं) के लिए असफल रहा .Advanced.DatabaseCommands.UpdateByIndex (..) '। क्या यह अपेक्षित व्यवहार है? – biofractal

+0

एचआरएम, यह एक नियमित क्वेरी से अलग होगा। मुझे इसे देखना होगा (या लागू करने के लिए कुछ सुझाव देना होगा) क्योंकि ऐसा करने के लिए एक गैर-आक्रामक तरीका होना चाहिए। – Rangoric

+2

एक श्रोता का उपयोग निश्चित रूप से स्वीकार किए गए उत्तर के अनुसार एक विस्तार विधि को कॉल करने से बेहतर बेहतर हस्तक्षेप समाधान होगा, हालांकि अब तक कोई भी दस्तावेज़स्टोर स्तर तय करने के लिए थोक अद्यतन के साथ काम नहीं करता है यानी जब मैं 'UpdateByIndex' के माध्यम से एक अनुक्रमणिका का उपयोग करता हूं (..) '। सौभाग्य! – biofractal

1

पता है कि StaleIndexes भी abondoned शामिल और विकलांग सूचकांकों हो - जो कभी नहीं तारीख तक मिल जाएगा।

तो indefinetely बजाय इस संपत्ति का उपयोग इंतजार कर से बचने के लिए:

var staleIndices = store.DatabaseCommands.GetStatistics().CountOfStaleIndexesExcludingDisabledAndAbandoned; 
+0

बस एक समस्या में फंस गया क्योंकि स्टेल इंडेक्स में भी छोड़ दिया गया है। आपका दृष्टिकोण इसे हल करने लगता है। – Fjut

संबंधित मुद्दे