Lucene.Net and I/O Threading issue - multithreading

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.
This is the error message I got
"Lock obtain timed out: SimpleFSLock error...."
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
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.
Thanks

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.
You might find this post helpful.

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.
In "IndexWriter", you have
Lock #lock = this.directory.MakeLock("write.lock");
if (!#lock.Obtain(this.writeLockTimeout))
which is pointed to the SimpleFSLock implementation. The culprit was
new FileStream(this.lockFile.FullName, FileMode.CreateNew).Close();
by creating a new thread, internally, it throws a system.unauthorizedaccessexception, according to msdn here
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.
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().
Such, I solved my issue by impersonate the IIS account running my application in "Execute()" function and all problems are resolved.
Thanks again to all.

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.
Otherwise, hopefully someone more familiar with Lucene.net can answer.

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.

Related

method synchronization in UI automation using Geb+Spock+Gradle+groovy

Background : I am using Geb+Spock+ Gradle for UI Test automation and using build.gradle file
which contains following config:
tasks.withType(Test) {
maxParallelForks = 2
forkEvery = 1
include '**/*TestSuite*.class'
}
now,there are two suites ->
TestSuite1.class
and
TestSuite2.class
both are running in parallel using multiForking with the help of above config.
Both suite contains UI testcases which intend to verify the status of a payment on a Sandbox,
Actual Problem :Sandbox allow only 1 login at a time (session expires if other thread try to verify the payment status)
I want to run the payment verification method in a synchronized way so that payment verification could be done by one thread at a time(while other thread waits).
Regards
Niks
First of all, for the example you showed, Gradle works in a way that it starts a new JVM, a separate process, for every TestSuite. This means that this is not a multithreading problem, but a rather a process synchronization problem.
You will need to create some kind of lock for your processes.
The most basic way that I can think of is creating a lock directory on the file system.
Write a utility method, that checks if the lock directory is present, and if it is, wait for it to disappear to continue.
If the directory is not present, create the directory.
Then access the payment sandbox, only if you have created the directory.
Be aware that there might be a race condition, depending on your implementation.
But it should not be a problem in practice. Since UI tests are rather slow, you will probably not be requesting in a frequency high enough to ever notice it.

XPages OpenLog - Logging to wrong database

Apologies Paul, this is a duplicate to the post I put on OpenNTF, however the site will not allow me to log in the last 2 days to follow up, plus the wider audience of Stack might find me someone with an identical issue.
To keep it short.
I have 1 openLog database in a folder structure, logs/xpageslog.nsf
During development, I could log to this database, for example, using Paul Withers XPages OpenLog Logger, to log uncaught exceptions with the following settings:
private String logDbName = "logs\\xpageslog.nsf"; // in OpenLogItem.java from OpenLogClass library
logDbName = "logs/xpages.nsf" // in OpenLogFunctions.ls
xsp.openlog.filepath=log/xpageslog.nsf // in xsp.properties
However, if I then change all the above, to simply go to xpageslog.nsf, in the root of the server (this is a 2nd openLog database) errors still get logged to the first database.
I've tried building, cleaning, re-compiling, all to no avail. It seem's to be that somewhere, or somehow, the references to the original database are not being overwritten.
Any ideas?
It is good practice to use restart task http instead of tell http restart. Both commands have different effects.
As confirmed in comments, this solved the problem.
Some use tell http quit followed by load http, the effect is the same as with restart task http. At the other hand, simple tell http restart does not fully initialize http task, it's kind of soft reset and I recommend not using it.

Liferay: perform an action when a -LocalServiceUtil is available

I have implemented a functional Liferay service using service builder and I want to call a method on the -LocalServiceUtil class just as soon as I possibly can. This is a task I wish to perform when the service starts and also when the service is redeployed.
Even though all the methods on the -LocalServiceUtil class are static, they will throw a BeanLocatorException if they are called too soon.
com.liferay.portal.kernel.bean.BeanLocatorException: BeanLocator has not been set for servlet context portal-navigation-impl
Is there any way to call a method on the -LocalServiceImpl instance or otherwise so that I can do this?
Thank you
As you speak about the initialization order: I'm not 100% sure about this, but I'd write a startup action. This gets run everytime a hook (or plugin) starts up - including a redeploy. Sounds like what you want - and if the initialization order works, this is your solution.
Otherwise: Create a separate hook that's dependent on the one that you're currently using. That will be restarted as well, but only run once the hook providing the *-LocalService did already start up. (dependency is declared in liferay-plugin-package.properties, with the key required-deployment-context - this is from memory - somebody correct me if I'm wrong.)

How to "clean" serialized files from filesystem without restarting http task

We have an XPages application and we serialize all pages on disk for this specific application. We already use the gzip option but it seems the serialized files are removed from disk only when the http task is stopped or restarted.
As this application is used by many different customers from different places around the globe, we try to avoid restart the server or the http task as much as possible but the drawback is that serialized files are never deleted ans so sooner or later we face a disk space problem even if the gzip serialzed files are not that big.
A secondary issue is that the http task takes quite a long time to stop because it has to remove all the serialized files.
Is there any way to have the domino server "clean" old/unused serialized files without restarting the http task ?
Currently we implemented an OS script which cleans serialized files older than tow days which is fine, but I would prefer a solution within domino.
Thanks in advance for your answers/suggestions !
Renaud
I believe the httpSessionId is used to store the file(s) on disk. You could try the following:
Alter the xsp.persistence.dir.xspstate to a friendlier location on (i.e. /temp/xspstate)
Register a SessionListener with your XPage application
Inside the SessionListener's sessionDestroyed method recursively search through the folders to find the one file or folder that matches the sessionId and delete
When the sessionDestoryed method is called in the listener any file locks should have been removed. Also note, as of right now, the seesionDestroyed method is not called right after a user logs out (see my question here: SessionListener sessionDestroyed not called)
hope this helps...

cherrypy: how to access file system from cherrypy?

I am working on a cherrpy web service to work with my web app. In this service it needs to be able to access the file system. For example, I want to be able to list all files under a certain directory. I am using os.walk('/public/') but don't seem to get it to work, even though the same code works outside of cherrpy.
Is there a way to make it work so I can use cherrypy to manage files?
What user is the webapp running as, and does it have access to read the folder?
According to the documentation os.walk() will ignore errors from the underlying calls to os.listdirs()
http://docs.python.org/release/2.4.4/lib/os-file-dir.html
You could try setting the onerror argument like
def print_error(error):
print error
os.walk('/public/', print_error)
which might give you a hint as to what's going on.
Also, you could try going directly to os.listdirs() and see if you get any errors from it.

Resources