2010-11-22 9 views
6

में Lucene.Net उपयोग के साथ निर्देशिका लॉक त्रुटि मैं एक एएसपी.नेट एमवीसी साइट बना रहा हूं जहां मैं खोज के लिए Lucene.Net का उपयोग करना चाहता हूं। मैंने पहले ही एक खोज नियंत्रक और इसकी सभी विधियों का निर्माण किया है, लेकिन मुझे रनटाइम पर एक त्रुटि मिल रही है जो तब होता है जब SearchController को पहली बार प्रारंभ किया जाता है।एएसपी.नेट एमवीसी साइट

SearchController में, यहाँ कैसे मैं एक IndexWriter बनाने हूँ: अंतिम पंक्ति पर

public static string IndexLocation = HostingEnvironment.MapPath("~/lucene"); 
public static Lucene.Net.Analysis.Standard.StandardAnalyzer analyzer = new Lucene.Net.Analysis.Standard.StandardAnalyzer(); 
public static IndexWriter writer = new IndexWriter(IndexLocation,analyzer); 

त्रुटि तब होती है। यहाँ संदेश है कि मैं हो रही है:

Lucene.Net.Store.LockObtainFailedException: \ उपयोगकर्ता नाम \ डेस्कटॉप \ SiteSolution \ साइट \ Lucene \ लिखने \ Users: लॉक का समय समाप्त हो प्राप्त: SimpleFSLock @ सी

[LockObtainFailedException: Lock obtain timed out: [email protected]:\Users\Username\Desktop\SiteSolution\Site\lucene\write.lock] 
    Lucene.Net.Store.Lock.Obtain(Int64 lockWaitTimeout) in C:\Users\Username\Desktop\Lucene.Net_2_9_2\src\Lucene.Net\Store\Lock.cs:107 
    Lucene.Net.Index.IndexWriter.Init(Directory d, Analyzer a, Boolean create, Boolean closeDir, IndexDeletionPolicy deletionPolicy, Boolean autoCommit, Int32 maxFieldLength, IndexingChain indexingChain, IndexCommit commit) in C:\Users\Username\Desktop\Lucene.Net_2_9_2\src\Lucene.Net\Index\IndexWriter.cs:1827 
    Lucene.Net.Index.IndexWriter.Init(Directory d, Analyzer a, Boolean closeDir, IndexDeletionPolicy deletionPolicy, Boolean autoCommit, Int32 maxFieldLength, IndexingChain indexingChain, IndexCommit commit) in C:\Users\Username\Desktop\Lucene.Net_2_9_2\src\Lucene.Net\Index\IndexWriter.cs:1801 
    Lucene.Net.Index.IndexWriter..ctor(String path, Analyzer a) in C:\Users\Username\Desktop\Lucene.Net_2_9_2\src\Lucene.Net\Index\IndexWriter.cs:1350 
    Site.Controllers.SearchController..cctor() in C:\Users\Username\Desktop\SiteSolution\Site\Controllers\SearchController.cs:95 

[TypeInitializationException: The type initializer for 'Site.Controllers.SearchController' threw an exception.] 

[TargetInvocationException: Exception has been thrown by the target of an invocation.] 
    System.RuntimeTypeHandle.CreateInstance(RuntimeType type, Boolean publicOnly, Boolean noCheck, Boolean& canBeCached, RuntimeMethodHandle& ctor, Boolean& bNeedSecurityCheck) +0 
    System.RuntimeType.CreateInstanceSlow(Boolean publicOnly, Boolean fillCache) +86 
    System.RuntimeType.CreateInstanceImpl(Boolean publicOnly, Boolean skipVisibilityChecks, Boolean fillCache) +230 
    System.Activator.CreateInstance(Type type, Boolean nonPublic) +67 
    System.Web.Mvc.DefaultControllerFactory.GetControllerInstance(RequestContext requestContext, Type controllerType) +80 

[InvalidOperationException: An error occurred when trying to create a controller of type 'Site.Controllers.SearchController'. Make sure that the controller has a parameterless public constructor.] 
    System.Web.Mvc.DefaultControllerFactory.GetControllerInstance(RequestContext requestContext, Type controllerType) +190 
    System.Web.Mvc.DefaultControllerFactory.CreateController(RequestContext requestContext, String controllerName) +68 
    System.Web.Mvc.MvcHandler.ProcessRequestInit(HttpContextBase httpContext, IController& controller, IControllerFactory& factory) +118 
    System.Web.Mvc.MvcHandler.BeginProcessRequest(HttpContextBase httpContext, AsyncCallback callback, Object state) +46 
    System.Web.Mvc.MvcHandler.BeginProcessRequest(HttpContext httpContext, AsyncCallback callback, Object state) +63 
    System.Web.Mvc.MvcHandler.System.Web.IHttpAsyncHandler.BeginProcessRequest(HttpContext context, AsyncCallback cb, Object extraData) +13 
    System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +8682818 
    System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +155 

मैं इस मुद्दे का समाधान कैसे कर सकते हैं: .lock

इसके अलावा, यहां स्टैक ट्रेस है?

अद्यतन: मैंने इस विशेष परियोजना पर फिर से काम करना शुरू कर दिया है, और ऐसा लगता है कि मैंने अभी तक इस मुद्दे को पूरी तरह से हल नहीं किया है।

असली मुद्दा यह है कि write.lock फ़ाइल इंडेक्स उपयोग समाप्त होने के बाद हटाया नहीं जा रहा है। मेरे द्वारा स्वीकार किए गए उत्तर के आधार पर, मैं बुनियादी कार्यान्वयन तर्क को समझता हूं, लेकिन मुझे यकीन नहीं है कि मैंने इसे सही तरीके से कार्यान्वित किया है या नहीं। यहां मेरी कक्षा में कुछ अन्य विधियां दी गई हैं जो शायद अमान्य हैं:

public ActionResult Search(string query) 
    { 

     var reader = writer.GetReader(); // Get reader from writer 
     var searcher = new IndexSearcher(reader); // Build IndexSearch 

     //Execute search... 

     // Dispose of objects 
     searcher = null; 
     reader = null; 

     return View(); 
    } 

    public void AddToIndex(Document doc) 
    { 
     writer.AddDocument(doc); 
     writer.Flush(); 
     writer.Optimize(); 
     writer.Flush(); 
    } 

    private bool disposed = false; 

    protected override void Dispose(bool disposing) 
    { 
     if (!disposed) 
     { 
      if (disposing) 
      { 
       // Release managed resources. 
      } 
      try 
      { 
       writer.Close(); 
       writer = null; 
      } 
      catch 
      { 

      } 
      // Release unmanaged resources. 
      // Set large fields to null. 
      // Call Dispose on your base class. 
      disposed = true; 
     } 
     base.Dispose(disposing); 
    } 

कोई विचार?

उत्तर

9

ऐसा क्यों होता है कि लेखक एक खाली फ़ाइल बनाता है जिसे क्रॉस-प्रोसेस लॉक के रूप में write.lock कहते हैं। जब वह फ़ाइल मौजूद होती है, तो लुसेन मानती है कि उस निर्देशिका में किसी के पास एक लिखना लॉक है।

जब आप अपनी प्रक्रिया को गलत तरीके से समाप्त करते हैं, तो फ़ाइल हटाई नहीं जाएगी। तो लुसीन सोचता है कि कोई अभी भी लॉक पर है। यही कारण है कि आपके पास हमेशा finally कथन होना चाहिए जो सूचकांक को बंद कर देता है।

यदि आप सुनिश्चित हैं कि फ़ाइल त्रुटि में है (यानी कोई लुसीन प्रक्रियाएं चल रही हैं) तो फ़ाइल को हटाने के लिए ठीक है। हालांकि, आपकी अनुक्रमणिका एक दूषित राज्य में हो सकती है, क्योंकि लेखन स्पष्ट रूप से मध्यप्रदेश को समाप्त कर दिया गया था।

+0

आपके उत्तर के लिए धन्यवाद! मेरा स्थिर सूचकांक लेखक वास्तव में कभी बंद नहीं होता ... क्या यह एक समस्या है? –

+0

@ मैक्सिम: एकमात्र कारण यह है कि एक समस्या होगी यदि एकाधिक प्रक्रियाओं को लिखने की आवश्यकता है। अन्यथा, लेखक को खोलने के लिए आमतौर पर सबसे अच्छा होता है और डिस्क पर फ्लश करने का निर्णय लेते हैं। – Xodarap

+0

@Xodarap: मैंने इस परियोजना पर फिर से काम करना शुरू कर दिया है, और मैंने अभी भी इस मुद्दे को पूरी तरह से ठीक नहीं किया है। मैं जिस कोड का उपयोग कर रहा हूं उसके साथ मैं प्रश्न को अपडेट करने जा रहा हूं। मैं बुनियादी कार्यान्वयन तर्क को समझता हूं, लेकिन मुझे यकीन नहीं है कि मैंने इसे सही तरीके से कार्यान्वित किया है या नहीं। –

2

लुसीन पर मृत-लॉक होने लगता है।

माना जाता है कि संग्रह में कोई अनुक्रमणिका का अद्यतन,
बस इस लॉक फ़ाइल C:\Users\Username\Desktop\SiteSolution\Site\lucene\write.lock निकालते हैं।

उसके बाद इंडेक्स लेखन फिर से चलाएं।

1
try 
{ 
    writer = new IndexWriter(directory, new StandardAnalyzer(), IndexWriter.MaxFieldLength.UNLIMITED); 
} 

catch (LockObtainFailedException ex) 
{ 
    DirectoryInfo indexDirInfo = new DirectoryInfo(directory); 
    FSDirectory indexFSDir = FSDirectory.Open(indexDirInfo, new Lucene.Net.Store.SimpleFSLockFactory(indexDirInfo)); 
    IndexWriter.Unlock(indexFSDir); 
    writer = new IndexWriter(directory, new StandardAnalyzer(), IndexWriter.MaxFieldLength.UNLIMITED); 
} 
+1

यह कोड संकलित नहीं करता है। DirectoryInfo कन्स्ट्रक्टर एक स्ट्रिंग लेता है, न कि AzureDirectory ऑब्जेक्ट। शायद मुझे कुछ याद आ रहा है। –

+0

यदि आप DirectoryInfo() में निर्देशिका के बजाय इंडेक्स स्थान पथ स्ट्रिंग में पास करते हैं, तो यह कोड काम करता है। –

0

इस अपने आप को शोध ऐसा लगता है कि indended दृष्टिकोण कई शारीरिक अनुक्रमणिका का उपयोग करें और फिर सभी समवर्ती सूचकांक परिवर्तन मर्ज करने के लिए IndexWriter के .addIndexesNoOptimize या .addIndexes का उपयोग कर उन्हें एक करना होगा।

Lucene documentation

0

इसे अपने आप को चेक नहीं किया गया है लेकिन इस काम (azureDirectory वस्तु बनाने के बाद लिखना) हैं?

azureDirectory.ClearLock("write.lock") 
0

मैं एक ही मुद्दे का सामना करना पड़ा है और मैं एक IProviderContext उपयोग कर रहा था। मेरे मामले में मुझे यह करना था: ProviderContext को अनुकूलित, प्रतिबद्ध और निपटान करें।

providerContext.Optimize(); 
providerContext.Commit(); 
providerContext.Dispose(); 

मुझे उम्मीद है कि इससे मदद मिलती है। उपरोक्त स्निपेट को लागू करने के बाद, मेरी अनुक्रमणिका सफलतापूर्वक पुनर्निर्मित की गई।

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