Lucene.NET --> access denied to segments - asp.net

I have a problem with Lucene.NET. During an index, I receive the error 'Access to the path segments is denied'. Or sometimes 'Access to the path deletable is denied'. I eventually gave 'Everyone' full security rights to the index directory, but the problem still existed.
I then found out that during the index run, lucene renames the segments file to 'segments.new', and then this error happens. I guess some process still tries to read from the old segments file after it has been renamed? I have no clue as to why this happens, or how to fix this. Strangely enough, my co-developers can run the index on their computer without a problem.
The error happens at happens in Lucene.Net.Index.IndexModifier.AddDocument(Document).
Any ideas would be much appreciated.

I suspect that your IndexModifier is in contention with a Searcher.
Here's how I use Lucene.Net in my bug tracking app, BugTracker.NET, which seems to be working ok.
I create the index at app startup.
I create a searcher and keep it around so that the index isn't reloaded with each search. All threads share the same searcher. When the searcher searches, it grabs a lock, searches, then releases the lock, so that another thread can search. Forces the searches into single file is doable in my app because Lucene.NET is quick and a bug tracking system isn't THAT busy.
Meanwhile, I have an IndexWriter that updates the index when there is a data change. It is just changing a little bit so it does its task quick too. When it needs to run, it grabs the same lock, destroys the searcher, updates the index, and the re-recreates the searcher. The new searcher stays around until the next update of the index. The searcher always is working with an up-to-date index.
You can get the BugTracker.NET source and look at the files my_lucene.cs and search_text.aspx. It's all in those two files, and there isn't that much code.

This problem is caused by an online virus scanner locking the segments(.new) file. I have had to write a custom Lucene Directory implementation to work around this.

I think i found a solution.. well at least it worked for me..
I was testing for the "segments.new" problem and below you have the code .. so as you can see in a loop i created thousands of lucene documents (6000).. At about 1360 document an error appears saying that he couldn´t rename blablabla.. The code is written in c#.. basically you just have to insert a try catch (inside the loop) for the error and when the error pops up you just try again subtracting the int loop nunmber(y) by one (y = y - 1) ..
//-----------------Problem -------------------------------------
for (int y = 0; y < 6000; y++)
{
Document doc = new Document();
doc.Add(new Field("URL", "C:/Users/blabla/(convert-csharp)/IMssg", Field.Store.YES, Field.Index.TOKENIZED));
writer.AddDocument(doc);
}
//--------------------Solution----------------------------------------
IndexWriter writer = new IndexWriter("C:/Users/blabla/(convert-csharp)/IMssg", new StandardAnalyzer(), false);
for (int y = 0; y < 6000; y++)
{
try
{
Document doc = new Document();
doc.Add(new Field("URL", "C:/Users/blabla/(convert-csharp)/IMssg", Field.Store.YES, Field.Index.TOKENIZED));
writer.AddDocument(doc);
}
catch (Exception t)
{
y = (y < 0) ? 0 : y - 1;
string gfff = t.Message.ToString();
}
}
writer.Close();
Im not a english guy so im sory if there´s any error in some word...
by now
regards immanouel

I second Imma's solution. I had this problem also. The fix for me was to put the try/catch around IndexWriter.AddDocument(doc):
int attemptNo = 0;
while (attemptNo < 2)
{
try
{
writer.AddDocument(doc);
break;
}
catch (Exception e)
{
String ErrMsg = String.Format("{0} ({1}): While adding Document {2}/{3}, caught {4}", DateTime.Now, attemptNo, doc.GetField("kanji").StringValue(), doc.GetField("kana").StringValue(), e.Message);
attemptNo++;
System.Threading.Thread.Sleep(30);
Application.Current.Dispatcher.Invoke(System.Windows.Threading.DispatcherPriority.Normal, (Action)delegate()
{
ViewModel.Log.Add(ErrMsg);
});
}
reference: http://issues.apache.org/jira/browse/LUCENE-665:
"The gist of the issue is: on Windows, you sometimes see intermittant
"Access Denied" errors in renaming segments.new to segments or
deletable.new to deletable, etc. Lucene typically writes files first
to X.new and then renames then to X."

I read about this. However, I do not have any virus scanners running. I also disabled Vista Search Index for the index directory, killed the search index process from the task manager, to make sure no other process is locking the file. Unfortunately, to no avail. Moreover, the problem seems more to be that the 'segments' file it tries to access, is gone (since lucene renamed it to segments.new). I'm not sure if they are the same problems...

Related

System.Io.Directory::GetFiles() Polling from AX 2009, Only Seeing New Files Every 10s

I wrote code in AX 2009 to poll a directory on a network drive, every 1 second, waiting for a response file from another system. I noticed that using a file explorer window, I could see the file appear, yet my code was not seeing and processing the file for several seconds - up to 9 seconds (and 9 polls) after the file appeared!
The AX code calls System.IO.Directory::GetFiles() using ClrInterop:
interopPerm = new InteropPermission(InteropKind::ClrInterop);
interopPerm.assert();
files = System.IO.Directory::GetFiles(#POLLDIR,'*.csv');
// etc...
CodeAccessPermission::revertAssert();
After much experimentation, it emerges that the first time in my program's lifetime, that I call ::GetFiles(), it starts a notional "ticking clock" with a period of 10 seconds. Only calls every 10 seconds find any new files that may have appeared, though they do still report files that were found on an earlier 10s "tick" since the first call to ::GetFiles().
If, when I start the program, the file is not there, then all the other calls to ::GetFiles(), 1 second after the first call, 2 seconds after, etc., up to 9 seconds after, simply do not see the file, even though it may have sitting there since 0.5s after the first call!
Then, reliably, and repeatably, the call 10s after the first call, will find the file. Then no calls from 11s to 19s will see any new file that might have appeared, yet the call 20s after the first call, will reliably see any new files. And so on, every 10 seconds.
Further investigation revealed that if the polled directory is on the AX AOS machine, this does not happen, and the file is found immediately, as one would expect, on the call after the file appears in the directory.
But this figure of 10s is reliable and repeatable, no matter what network drive I poll, no matter what server it's on.
Our network certainly doesn't have 10s of latency to see files; as I said, a file explorer window on the polled directory sees the file immediately.
What is going on?
Sounds like your issue is due to SMB caching - from this technet page:
Name, type, and ID
Directory Cache [DWORD] DirectoryCacheLifetime
Registry key the cache setting is controlled by
HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Lanmanworkstation\Parameters
This is a cache of recent directory enumerations performed by the
client. Subsequent enumeration requests made by client applications as
well as metadata queries for files in the directory can be satisfied
from the cache. The client also uses the directory cache to determine
the presence or absence of a file in the directory and uses that
information to prevent clients from repeatedly attempting to open
files which are known not to exist on the server. This cache is likely
to affect distributed applications running on multiple computers
accessing a set of files on a server – where the applications use an
out of band mechanism to signal each other about
modification/addition/deletion of files on the server.
In short try to set the registry key
HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Lanmanworkstation\Parameters\DirectoryCacheLifetime
to 0
Thanks to #Jan B. Kjeldsen , I have been able to solve my problem using FileSystemWatcher. Here is my implementation in X++ :
class SelTestThreadDirPolling
{
}
public server static Container SetStaticFileWatcher(str _dirPath,str _filenamePattern,int _timeoutMs)
{
InteropPermission interopPerm;
System.IO.FileSystemWatcher fw;
System.IO.WatcherChangeTypes watcherChangeType;
System.IO.WaitForChangedResult res;
Container cont;
str fileName;
str oldFileName;
str changeType;
;
interopPerm = new InteropPermission(InteropKind::ClrInterop);
interopPerm.assert();
fw = new System.IO.FileSystemWatcher();
fw.set_Path(_dirPath);
fw.set_IncludeSubdirectories(false);
fw.set_Filter(_filenamePattern);
watcherChangeType = ClrInterop::parseClrEnum('System.IO.WatcherChangeTypes', 'Created');
res = fw.WaitForChanged(watcherChangeType,_timeoutMs);
if (res.get_TimedOut()) return conNull();
fileName = res.get_Name();
//ChangeTypeName can be: Created, Deleted, Renamed and Changed
changeType = System.Enum::GetName(watcherChangeType.GetType(), res.get_ChangeType());
fw.Dispose();
CodeAccessPermission::revertAssert();
if (changeType == 'Renamed') oldFileName = res.get_OldName();
cont += fileName;
cont += changeType;
cont += oldFileName;
return cont;
}
void waitFileSystemWatcher(str _dirPath,str _filenamePattern,int _timeoutMs)
{
container cResult;
str filename,changeType,oldFilename;
;
cResult=SelTestThreadDirPolling::SetStaticFileWatcher(_dirPath,_filenamePattern,_timeoutMs);
if (cResult)
{
[filename,changeType,oldFilename]=cResult;
info(strfmt("filename=%1, changeType=%2, oldFilename=%3",filename,changeType,oldFilename));
}
else
{
info("TIMED OUT");
}
}
void run()
{;
this.waitFileSystemWatcher(#'\\myserver\mydir','filepattern*.csv',10000);
}
I should acknowledge the following for forming the basis of my X++ implementation:
https://blogs.msdn.microsoft.com/floditt/2008/09/01/how-to-implement-filesystemwatcher-with-x/
I would guess DAXaholic's answer is correct, but you could try other solutions like EnumerateFiles.
In your case I would rather wait for the files rather than poll for the files.
Using FileSystemWatcher there will be a minimal delay from file creation till your process wakes up. It is more tricky to use, but avoiding polling is a good thing. I have never used it over a network.

Understanding the JIT; slow website

First off, this question has been covered a few times (I've done my research), and, for example, on the right side of the SO webpage is a list of related items... I have been through them all (or as many as I could find).
When I publish my pre-compiled .NET web application, it is very slow to load the first time.
I've read up on this, it's the JIT which I understand (sort of).
The problem is, after the home page loads (up to 20 seconds), many other pages load very fast.
However, it would appear that the only reason they load is because the resources have been loaded (or that they share the same compiled dlls). However, some pages still take a long time.
This indicates that maybe the JIT needs to compile different pages in different ways? If so, and using a contact form as an example (where the Thank You page needs to be compiled by the JIT and first time is slow), the user may hit the send button multiple times whilst waiting for the page to be shown.
After I load all these pages which use different models or different shared HTML content, the site loads quickly as expected. I assume this issue is a common problem?
Please note, I'm using .NET 4.0 but, there is no database, XML files etc. The only IO is if an email doesn't send and it writes the error to a log.
So, assuming my understanding is correct, what is the approach to not have to manually go through the website and load every page?
If the above is a little too broad, then can this be resolved in the settings/configuration in Visual Studio (2012) or the web.config file (excluding adding compilation debug=false)?
In this case, there are 2 problems
As per rene's comments, review this http://msdn.microsoft.com/en-us/library/ms972959.aspx... The helpful part was to add the following code to the global.asax file
const string sourceName = ".NET Runtime";
const string serverName = ".";
const string logName = "Application";
const string uriFormat = "\r\n\r\nURI: {0}\r\n\r\n";
const string exceptionFormat = "{0}: \"{1}\"\r\n{2}\r\n\r\n";
void Application_Error(Object sender, EventArgs ea) {
StringBuilder message = new StringBuilder();
if (Request != null) {
message.AppendFormat(uriFormat, Request.Path);
}
if (Server != null) {
Exception e;
for (e = Server.GetLastError(); e != null; e = e.InnerException) {
message.AppendFormat(exceptionFormat,
e.GetType().Name,
e.Message,
e.StackTrace);
}
}
if (!EventLog.SourceExists(sourceName)) {
EventLog.CreateEventSource(sourceName, logName);
}
EventLog Log = new EventLog(logName, serverName, sourceName);
Log.WriteEntry(message.ToString(), EventLogEntryType.Error);
//Server.ClearError(); // uncomment this to cancel the error
}
The server was maxing out during sending of the email! My code was fine, but, viewing Task Scheduler showed it was hitting 100% memory...
The solution was to monitor the errors shown by point 1 and fix it. Then, find out why the server was being throttled when sending an email!

Closer to bypassing Flex print dialogue?

I know this is a pretty heavy topic and see requests for it all the time (I believe the stance for blocking it is security related).
While messing around trying to get ZPL printing working in AIR, I ran into something interesting.
Looking at other programming languages and their attempts to print to ZPL, most of them handle it through a File Stream and treat the printer as a file (see here for a .NET example .NET code to send ZPL to Zebra printers).
I took this approach with Flex and got some interesting results.
I tested this talking directly to a network shared printer on my own PC. It's a simple piece of code:
var file:File = new File('\\\\PC-Name\\Printer-Name');
var stream:FileStream = new FileStream();
stream.open(file, FileMode.WRITE);
Obviously you will need to fill in your own info for PC-Name (network name) and Printer-Name (printer's shared name).
If you watch your printer, you'll notice that it does initiate spooling with this request.
Unfortunately, this is about as far as I'm able to get with it. Initiating any sort of actually writing over that stream doesn't seem to work (although I'm far from an expert on the matter, I could be missing something).
Stepping through something like:
var file:File = new File('\\\\PC-Name\\Printer-Name');
var stream:FileStream = new FileStream();
stream.open(file, FileMode.WRITE);
stream.close();
You can watch it hit the spooler with the open and then successfully close without any ill effects.
Once you add an actual write though such as:
var byteArray:ByteArray = new ByteArray();
byteArray.writeUTFBytes("Hello World");
byteArray.position = 0;
var file:File = new File('\\\\PC-Name\\Printer-Name');
var stream:FileStream = new FileStream();
stream.open(file, FileMode.WRITE);
stream.writeBytes(byteArray, 0, byteArray.length);
stream.close();
It all goes to hell unfortunately.
Some things to note about the variables and what happens:
After declaring your file (var file:File = new File('\\PC-Name\Printer-Name');), when you inspect the file variable you'll notice a few issues. creationDate, modificationDate, and size all have "exception thrown by getter" errors. More specifically "Error: Error #3003: File or directory does not exist.". I'm not overly concerned with these as it isn't a file, it's a printer.
After opening the stream (stream.open(file, FileMode.WRITE);) and inspecting the stream variable the "bytesAvailable" has an "exception thrown by getter" (Error: Error #2029: This URLStream object does not have a stream opened). Once again, it isn't a file so the bytesAvailable like this might be okay (or it may be the reason everything after this seems to fail). At this point, you will also have a print document with a status of "Spooling" in your print queue.
Calling stream.writeBytes(byteArray, 0, byteArray.length); causes the stream variable position to move from 0 to 167 (the length of my byteArray). So it seems to think it attempts to write. Nothing "bad" seems to happen here.....
Calling stream.close(); however, brings the whole thing crashing down with a "Error #2038: File I/O Error. at flash.filesystem::FileStream/close()
Posting this here to see if anyone has any ideas (am I missing something? Is it completely not possible? Close but no cigar?)
******** UPDATE *********
I did find a way to accomplish this with a network printer (unfortunately not with a windows shared printer). It is using sockets instead of filestreams. I can almost guarantee you this will throw some sandbox violations upon an actual release so that will need to be handled (socket policy files I would assume).
public var socket:Socket = new Socket();
socket.addEventListener( Event.CONNECT, onConnect);
socket.addEventListener( ProgressEvent.SOCKET_DATA, onSocketData);
socket.connect(ip_address, 9100);
private function onConnect(event : Event) : void {
var byteArray:ByteArray = new ByteArray();
byteArray.writeUTFBytes("Hello World");
byteArray.position = 0;
socket.writeBytes(byteArray, 0, byteArray.length);
socket.removeEventListener(Event.CONNECT, onConnect);
socket.removeEventListener(ProgressEvent.SOCKET_DATA, onSocketData);
socket.flush();
socket.close();
}
public function onSocketData(event:Event):void {
trace("onSocketData Fired");
}
Not sure if one can even connect over a socket to a windows shared printer (ie a printer connected to someone's PC and shared). So far I haven't had any luck. But, if you are strictly dealing with networked printers this might work for you to skip/bypass the flex print dialogue.
I'm making a few assumptions: If you're using AIR and you have a working .Net solution and you are targeting Windows only... why not just use the .Net solution and call it using NativeProcess class?
Basically you compile the ZPL .NET printer as an EXE and call it using NativeProcess, passing in the printer string.
That way you can still have a nice Flexy interface but get native printing controls.

Browse a file from my pc using web application in asp.net

I have a web application which I uploaded using IIS. I want the users using the application would be able to select a file located on their (the user) computer and read its contents.
The code is:
TextReader trs = new StreamReader(faFile.Value);
DataAccessLayer.clearFA();
string line = trs.ReadLine();
// Read all unneeded data
while (line != "** Start Data **")
{
line = trs.ReadLine();
}
line = trs.ReadLine();
while (line != null)
{
string[] words = line.Split('*');
// There is no message
if (words[4] == "")
{
DataAccessLayer.insertIntoFA(Int32.Parse(words[1]), words[3].Replace("'", ""));
}
else
{
DataAccessLayer.insertIntoFA(Int32.Parse(words[1]), words[4].Replace("'", ""));
}
line = trs.ReadLine();
}
}
When I run it from my pc it works. But when I try to run it from the IIS it gives me the following error:
Could not find a part of the path 'C:\Documents and Settings\myUser\Desktop\file.txt'.
I understand that the application cant read the file from the user pc. Any idea how can I make it work?
Thanks!
Greg
This is done for security reasons - a browser does not have access to the filesystem of the user.
There is no way to work around this, as all other technologies running inside a browser are sandboxed and limited (again, for security reasons).
The closest you can get is to use an <input type="file"> that lets the user to select a file for upload.
The upload file's path in IE 8 is a full path. You can obtain filename from the full name. Combine server path and filename before saving file

Blackberry JDE HTTPConnection problems

So, I'm using the HTTPConnection Class, like so:
HttpConnection c =
(HttpConnection)Connector.open("http://147.117.66.165:8000/eggs.3gp");
Following what LOOKS like the right way to do things in the Blackberry JDE API.
However, my code crashes if I try to do just about anything with the variable 'c'.
.getType()
.getInputStream()
.getStatus()
all cause it to crash.
I can, however get the URL from it, and I can look at the variable 'c' itself to know that it did, in fact, get created.
Did I manage to create a broken Connection? Do I need to do something else to actually do things with the connection? Under what circumanstances will this happen (I know the link is good, I can use the blackberry's browser to visit it).
Am I just using HttpConnection wrong? How would I do things correctly?
What error is it throwing when it crashes? You may want to try adding the "Connector.READ_WRITE" as a second argument to your open call - even if it's just a "read only" connection like a GET, some OSes such as 4.6 will throw an exception unless you open it in read/write mode.
I figured out what was wrong by finding some sample code that was using HttpConnection, (at least, I think I did, at least, I can access all those variables, now). Before, I wasn't ever casting it as a "Stream Connection" (the examples I saw had it cast from Connector to HTTPConnection).
StreamConnection s = null;
s = (StreamConnection)Connector.open("http://10.252.9.15/eggs.3gp");
HttpConnection c = (HttpConnection)s;
InputStream i = c.openInputStream();
System.out.println("~~~~~I have a connection?~~~~~~" + c);
System.out.println("~~~~~I have a URL?~~~~" + c.getURL());
System.out.println("~~~~~I have a type?~~~~" + c.getType());
System.out.println("~~~~~I have a status?~~~~~~" + c.getResponseCode());
System.out.println("~~~~~I have a stream?~~~~~~" + i);
player = Manager.createPlayer(i, c.getType());
Even though the stream is now successfully being created, I'm still having problems USING it, but that might be because my connection is so slow.
The API documentation for HttpConnection suggests the first call should be to c.getResponseCode(), try that.
You should find everything you need in my blog post "An HttpRequest and HttpResponse library for BB OS5+"
And for invoking media within your application you can do either a browser invokation or directly from app. You would probably be best to use the browser like so:
BrowserSession invokeHighQuality = Browser.getDefaultSession();
invokeHighQuality.displayPage("URL goes here");
OR you can try this:
// CHAPI invocation
Invocation invoke = new Invocation(_data.getUrl(), null, BlackBerryContentHandler.ID_MEDIA_CONTENT_HANDLER, false,
null);
try {
Registry.getRegistry(YourAppClass.class.getName()).invoke(invoke);
} catch (Throwable t) {
}

Resources