Lucene.Net和I / O线程问题

时间:2022-03-17 03:06:53

I have an indexing function named "Execute()" using IndexWriter to index my site's content. It works great if I simply called it from a web page, but failed when I have it as a delegate parameter into System.Threading.Thread. Strangely though, it always work on my local dev machine, it only fails when I uploads to a shared host.

我有一个名为“Execute()”的索引函数,使用IndexWriter索引我的网站的内容。如果我只是从网页上调用它,它的效果很好,但是当我将它作为委托参数输入System.Threading.Thread时失败了。奇怪的是,它总是在我的本地开发机器上工作,它只在我上传到共享主机时失败。

This is the error message I got

这是我收到的错误消息

"Lock obtain timed out: SimpleFSLock error...."

“锁定获得超时:SimpleFSLock错误......”

Below is the failed code (but only fails on a shared host)

以下是失败的代码(但只在共享主机上失败)

Scheduler scheduler = new Scheduler();
System.Threading.Thread schedulerThread = new System.Threading.Thread(scheduler.Execute);

Below is the code that works (work both on my local machine and on shared host)

以下是有效的代码(在我的本地计算机和共享主机上工作)

Scheduler scheduler = new Scheduler();
schedulre.Execute();

Now, some ppl said, it could be a bad left over from the previous debugging session, so before I instantiated the IndexWriter, I did

现在,一些ppl说,它可能是以前的调试会话遗留下来的坏事,所以在我实例化IndexWriter之前,我做了

if (IndexReader.IsLocked(indexingFolder))
{

    log.Debug("it is locked");
    IndexReader.Unlock(FSDirectory.GetDirectory(indexingFolder));
}
else
{
    log.Debug("it is not locked");
}

and guess what? my log says, it is not locked.

你猜怎么着?我的日志说,它没有锁定。

So now I'm pretty sure it's caused by the System.Thread.Threading, but I just have no clue as to how to fix it.

所以现在我很确定它是由System.Thread.Threading造成的,但我不知道如何修复它。

Thanks

4 个解决方案

#1


Check that on the shared host, the thread has the same permissions to the index folder as you do on the development machine/shared host.

检查共享主机上的线程是否与开发计算机/共享主机上的索引文件夹具有相同的权限。

Update: You can find what Principal the thread is running under by interrogating the thread's CurrentPrincipal property. Though this is a read-write property, you may not have the permissions to set this property in your shared-host environment.

更新:您可以通过询问线程的CurrentPrincipal属性来查找线程正在运行的Principal。虽然这是一个读写属性,但您可能没有权限在共享主机环境中设置此属性。

You might find this post helpful.

您可能会发现这篇文章很有用。

#2


Thanks everyone and especially to Vinay for pointing me in the right direction. After much tracing, i finally decided to take a look at the source and see what's there.

谢谢大家,特别是Vinay指出我正确的方向。经过大量追踪后,我终于决定查看源代码,看看有什么。

In "IndexWriter", you have

在“IndexWriter”中,你有

  Lock @lock = this.directory.MakeLock("write.lock");
  if (!@lock.Obtain(this.writeLockTimeout))

which is pointed to the SimpleFSLock implementation. The culprit was

它指向SimpleFSLock实现。罪魁祸首是

new FileStream(this.lockFile.FullName, FileMode.CreateNew).Close();

by creating a new thread, internally, it throws a system.unauthorizedaccessexception, according to msdn here

根据msdn的说法,通过在内部创建一个新线程,它会抛出一个system.unauthorizedaccessexception

When starting a new thread, System.Security.Principal.WindowsIdentity.GetCurrent() returns the identity of the process, not necessarily the identity of the code that called Thread.Start(). This is important to remember when starting asynchronous delegates or threads in an impersonated ASP.NET thread.

启动新线程时,System.Security.Principal.WindowsIdentity.GetCurrent()返回进程的标识,不一定是调用Thread.Start()的代码的标识。在模拟的ASP.NET线程中启动异步委托或线程时,这一点很重要。

If you are in ASP.NET and want the new thread to start with the impersonated WindowsIdentity, pass the WindowsIdentity to the ThreadStart method. Once in the ThreadStart method, call WindowsIdentity.Impersonate().

如果您在ASP.NET中并希望新线程以模拟的WindowsIdentity开头,请将WindowsIdentity传递给ThreadStart方法。进入ThreadStart方法后,调用WindowsIdentity.Impersonate()。

Such, I solved my issue by impersonate the IIS account running my application in "Execute()" function and all problems are resolved.

这样,我通过冒充在“执行()”函数中运行我的应用程序的IIS帐户解决了我的问题,并解决了所有问题。

Thanks again to all.

再次感谢所有人。

#3


Probably the worst one to try and answer this since I haven't used lucene / shared hosting, but SimpleFSLock sounds like it's locking the lucene index file by using an explicit lock file on the file system (not quite the same as locking in threading). I'd say check to make sure you have configured the proper file paths and that file permissions are set correctly.

可能是最糟糕的一个尝试回答这个,因为我没有使用lucene /共享主机,但SimpleFSLock听起来像是通过在文件系统上使用显式锁文件来锁定lucene索引文件(与线程中的锁定不完全相同) 。我会说检查以确保您已配置正确的文件路径并且文件权限设置正确。

Otherwise, hopefully someone more familiar with Lucene.net can answer.

否则,希望更熟悉Lucene.net的人可以回答。

#4


I believe the problem is with a write lock file in the Lucene index directory. Go and list the directory's files. In Java Lucene, you would have seen a file named write.lock in the index directory, meaning that the index was not properly closed last time (maybe a process was abruptly stopped). In Lucene.net, look for a similarly named empty file. I believe the same mechanism will be used in Lucene.net. Try finding that file, erasing it and restarting Lucene.net.

我认为问题在于Lucene索引目录中的写锁文件。转到并列出目录的文件。在Java Lucene中,你会在索引目录中看到一个名为write.lock的文件,这意味着索引上次没有正确关闭(可能是一个进程突然停止)。在Lucene.net中,查找类似命名的空文件。我相信Lucene.net会使用相同的机制。尝试找到该文件,擦除它并重新启动Lucene.net。

#1


Check that on the shared host, the thread has the same permissions to the index folder as you do on the development machine/shared host.

检查共享主机上的线程是否与开发计算机/共享主机上的索引文件夹具有相同的权限。

Update: You can find what Principal the thread is running under by interrogating the thread's CurrentPrincipal property. Though this is a read-write property, you may not have the permissions to set this property in your shared-host environment.

更新:您可以通过询问线程的CurrentPrincipal属性来查找线程正在运行的Principal。虽然这是一个读写属性,但您可能没有权限在共享主机环境中设置此属性。

You might find this post helpful.

您可能会发现这篇文章很有用。

#2


Thanks everyone and especially to Vinay for pointing me in the right direction. After much tracing, i finally decided to take a look at the source and see what's there.

谢谢大家,特别是Vinay指出我正确的方向。经过大量追踪后,我终于决定查看源代码,看看有什么。

In "IndexWriter", you have

在“IndexWriter”中,你有

  Lock @lock = this.directory.MakeLock("write.lock");
  if (!@lock.Obtain(this.writeLockTimeout))

which is pointed to the SimpleFSLock implementation. The culprit was

它指向SimpleFSLock实现。罪魁祸首是

new FileStream(this.lockFile.FullName, FileMode.CreateNew).Close();

by creating a new thread, internally, it throws a system.unauthorizedaccessexception, according to msdn here

根据msdn的说法,通过在内部创建一个新线程,它会抛出一个system.unauthorizedaccessexception

When starting a new thread, System.Security.Principal.WindowsIdentity.GetCurrent() returns the identity of the process, not necessarily the identity of the code that called Thread.Start(). This is important to remember when starting asynchronous delegates or threads in an impersonated ASP.NET thread.

启动新线程时,System.Security.Principal.WindowsIdentity.GetCurrent()返回进程的标识,不一定是调用Thread.Start()的代码的标识。在模拟的ASP.NET线程中启动异步委托或线程时,这一点很重要。

If you are in ASP.NET and want the new thread to start with the impersonated WindowsIdentity, pass the WindowsIdentity to the ThreadStart method. Once in the ThreadStart method, call WindowsIdentity.Impersonate().

如果您在ASP.NET中并希望新线程以模拟的WindowsIdentity开头,请将WindowsIdentity传递给ThreadStart方法。进入ThreadStart方法后,调用WindowsIdentity.Impersonate()。

Such, I solved my issue by impersonate the IIS account running my application in "Execute()" function and all problems are resolved.

这样,我通过冒充在“执行()”函数中运行我的应用程序的IIS帐户解决了我的问题,并解决了所有问题。

Thanks again to all.

再次感谢所有人。

#3


Probably the worst one to try and answer this since I haven't used lucene / shared hosting, but SimpleFSLock sounds like it's locking the lucene index file by using an explicit lock file on the file system (not quite the same as locking in threading). I'd say check to make sure you have configured the proper file paths and that file permissions are set correctly.

可能是最糟糕的一个尝试回答这个,因为我没有使用lucene /共享主机,但SimpleFSLock听起来像是通过在文件系统上使用显式锁文件来锁定lucene索引文件(与线程中的锁定不完全相同) 。我会说检查以确保您已配置正确的文件路径并且文件权限设置正确。

Otherwise, hopefully someone more familiar with Lucene.net can answer.

否则,希望更熟悉Lucene.net的人可以回答。

#4


I believe the problem is with a write lock file in the Lucene index directory. Go and list the directory's files. In Java Lucene, you would have seen a file named write.lock in the index directory, meaning that the index was not properly closed last time (maybe a process was abruptly stopped). In Lucene.net, look for a similarly named empty file. I believe the same mechanism will be used in Lucene.net. Try finding that file, erasing it and restarting Lucene.net.

我认为问题在于Lucene索引目录中的写锁文件。转到并列出目录的文件。在Java Lucene中,你会在索引目录中看到一个名为write.lock的文件,这意味着索引上次没有正确关闭(可能是一个进程突然停止)。在Lucene.net中,查找类似命名的空文件。我相信Lucene.net会使用相同的机制。尝试找到该文件,擦除它并重新启动Lucene.net。