public override void Close() { _fileMutex.WaitOne(); try { var fileName = _name; //make sure it's all written out //we are only checking for null here in case Close is called multiple times if (_cacheDirIndexOutput != null) { _cacheDirIndexOutput.Flush(); _cacheDirIndexOutput.Close(); IndexInput cacheInput = null; try { cacheInput = CacheDirectory.OpenInput(fileName); } catch (IOException e) { //This would occur if the file doesn't exist! we previously threw when that happens so we'll keep //doing that for now but this is quicker than first checking if it exists and then opening it. throw; } if (cacheInput != null) { IndexOutput masterOutput = null; try { masterOutput = MasterDirectory.CreateOutput(fileName); cacheInput.CopyTo(masterOutput, fileName); } finally { masterOutput?.Close(); cacheInput?.Close(); } } #if FULLDEBUG Trace.WriteLine($"CLOSED WRITESTREAM {_name}"); #endif // clean up _cacheDirIndexOutput = null; } GC.SuppressFinalize(this); } finally { _fileMutex.ReleaseMutex(); } }
/// <summary> /// This will sync the requested file from master storage to the local fast cache storage /// </summary> /// <param name="fileName"></param> private void SyncLocally(string fileName) { //get the master file stream IndexInput masterInput = null; try { masterInput = MasterDirectory.OpenInput(fileName); } catch (IOException ex) { //this will be a file not found (FileNotFoundException) //TODO: It has been seen that OpenInput on the master can throw an exception due to a lucene file not found - which is very odd // we need to check if the master is being written first before the sync dir. And if the file does not exist in the master, // or the sync dir, then something has gone wrong, that shouldn't happen and we'll need to deal with that differently // because the index will be in a state where it's just not readable. //Hrmmm what to do? There's actually nothing that can be done :/ if we return false here then the instance of this item would be null //which will then cause exceptions further on and take down the app pool anyways. I've looked through the Lucene source and there //is no safety net to check against this situation, it just happily throws exceptions on a background thread. _loggingService.Log(new LogEntry(LogLevel.Error, ex, $"File not found")); throw ex; } if (masterInput != null) { IndexOutput cacheOutput = null; try { cacheOutput = CacheDirectory.CreateOutput(fileName); masterInput.CopyTo(cacheOutput, fileName); } finally { cacheOutput?.Close(); masterInput?.Close(); } } }