diff --git a/src/UmbracoExamine/LocalStorage/LocalTempStorageDirectory.cs b/src/UmbracoExamine/LocalStorage/LocalTempStorageDirectory.cs index 64d2765d00..d945184056 100644 --- a/src/UmbracoExamine/LocalStorage/LocalTempStorageDirectory.cs +++ b/src/UmbracoExamine/LocalStorage/LocalTempStorageDirectory.cs @@ -9,15 +9,21 @@ namespace UmbracoExamine.LocalStorage public class LocalTempStorageDirectory : SimpleFSDirectory { private readonly Lucene.Net.Store.Directory _realDirectory; - + public LocalTempStorageDirectory( DirectoryInfo tempStorageDir, Lucene.Net.Store.Directory realDirectory) : base(tempStorageDir) { _realDirectory = realDirectory; + Enabled = true; } + /// + /// If initialization fails, it will be disabled and then this will just wrap the 'real directory' + /// + internal bool Enabled { get; set; } + public override string[] ListAll() { //always from the real dir @@ -49,7 +55,11 @@ namespace UmbracoExamine.LocalStorage public override void DeleteFile(string name) { //perform on both dirs - base.DeleteFile(name); + if (Enabled) + { + base.DeleteFile(name); + } + _realDirectory.DeleteFile(name); } @@ -67,10 +77,14 @@ namespace UmbracoExamine.LocalStorage public override IndexOutput CreateOutput(string name) { //write to both indexes + if (Enabled) + { + return new MultiIndexOutput( + base.CreateOutput(name), + _realDirectory.CreateOutput(name)); + } - return new MultiIndexOutput( - base.CreateOutput(name), - _realDirectory.CreateOutput(name)); + return _realDirectory.CreateOutput(name); } /// @@ -78,13 +92,21 @@ namespace UmbracoExamine.LocalStorage /// public override IndexInput OpenInput(string name) { - //return the reader from the cache, not the real dir - return base.OpenInput(name); + if (Enabled) + { + //return the reader from the cache, not the real dir + return base.OpenInput(name); + } + + return _realDirectory.OpenInput(name); } public override void Dispose() { - base.Dispose(); + if (Enabled) + { + base.Dispose(); + } _realDirectory.Dispose(); } diff --git a/src/UmbracoExamine/LocalStorage/LocalTempStorageDirectoryTracker.cs b/src/UmbracoExamine/LocalStorage/LocalTempStorageDirectoryTracker.cs new file mode 100644 index 0000000000..d3c94715b3 --- /dev/null +++ b/src/UmbracoExamine/LocalStorage/LocalTempStorageDirectoryTracker.cs @@ -0,0 +1,29 @@ +using System.Collections.Concurrent; +using System.IO; +using Directory = Lucene.Net.Store.Directory; + +namespace UmbracoExamine.LocalStorage +{ + internal class LocalTempStorageDirectoryTracker + { + private readonly static LocalTempStorageDirectoryTracker Instance = new LocalTempStorageDirectoryTracker(); + private readonly ConcurrentDictionary _directories = new ConcurrentDictionary(); + + public static LocalTempStorageDirectoryTracker Current + { + get { return Instance; } + } + + public LocalTempStorageDirectory GetDirectory(DirectoryInfo dir, Directory realDir, bool disable = false) + { + var resolved = _directories.GetOrAdd(dir.FullName, s => new LocalTempStorageDirectory(dir, realDir)); + + if (disable) + { + resolved.Enabled = false; + } + + return resolved; + } + } +} \ No newline at end of file diff --git a/src/UmbracoExamine/LocalStorage/LocalTempStorageIndexer.cs b/src/UmbracoExamine/LocalStorage/LocalTempStorageIndexer.cs index 0d702c8e12..2e242c1284 100644 --- a/src/UmbracoExamine/LocalStorage/LocalTempStorageIndexer.cs +++ b/src/UmbracoExamine/LocalStorage/LocalTempStorageIndexer.cs @@ -16,10 +16,9 @@ namespace UmbracoExamine.LocalStorage { private string _tempPath; public Lucene.Net.Store.Directory LuceneDirectory { get; private set; } - private static readonly object Locker = new object(); + private readonly object _locker = new object(); public SnapshotDeletionPolicy Snapshotter { get; private set; } - private bool _syncStorage = false; - + public LocalTempStorageIndexer() { IndexDeletionPolicy policy = new KeepOnlyLastCommitDeletionPolicy(); @@ -32,121 +31,101 @@ namespace UmbracoExamine.LocalStorage _tempPath = Path.Combine(codegenPath, configuredPath.TrimStart('~', '/').Replace("/", "\\")); - if (config != null) - { - if (config["syncTempStorage"] != null) - { - var attempt = config["syncTempStorage"].TryConvertTo(); - if (attempt) - { - _syncStorage = attempt.Result; - } - } - } + var success = InitializeLocalIndexAndDirectory(baseLuceneDirectory, analyzer, configuredPath); - InitializeLocalIndexAndDirectory(baseLuceneDirectory, analyzer, configuredPath); + //create the custom lucene directory which will keep the main and temp FS's in sync + LuceneDirectory = LocalTempStorageDirectoryTracker.Current.GetDirectory( + new DirectoryInfo(_tempPath), + baseLuceneDirectory, + //flag to disable the mirrored folder if not successful + success == false); } - private void InitializeLocalIndexAndDirectory(Lucene.Net.Store.Directory baseLuceneDirectory, Analyzer analyzer, string configuredPath) + private bool InitializeLocalIndexAndDirectory(Lucene.Net.Store.Directory baseLuceneDirectory, Analyzer analyzer, string configuredPath) { - lock (Locker) + lock (_locker) { if (Directory.Exists(_tempPath) == false) { Directory.CreateDirectory(_tempPath); } - //if we are syncing storage to the main file system to temp files, then sync from the main FS to our temp FS - if (_syncStorage) + //copy index + + using (new IndexWriter( + //read from the underlying/default directory, not the temp codegen dir + baseLuceneDirectory, + analyzer, + Snapshotter, + IndexWriter.MaxFieldLength.UNLIMITED)) { - //copy index - - using (new IndexWriter( - //read from the underlying/default directory, not the temp codegen dir - baseLuceneDirectory, - analyzer, - Snapshotter, - IndexWriter.MaxFieldLength.UNLIMITED)) + try { - try + var basePath = IOHelper.MapPath(configuredPath); + + var commit = Snapshotter.Snapshot(); + var allSnapshotFiles = commit.GetFileNames().Concat(new[] { commit.GetSegmentsFileName() }) + .Distinct() + .ToArray(); + + var tempDir = new DirectoryInfo(_tempPath); + + //Get all files in the temp storage that don't exist in the snapshot collection, we want to remove these + var toRemove = tempDir.GetFiles() + .Select(x => x.Name) + .Except(allSnapshotFiles); + + using (var tempDirectory = new SimpleFSDirectory(tempDir)) { - var basePath = IOHelper.MapPath(configuredPath); - - var commit = Snapshotter.Snapshot(); - var allSnapshotFiles = commit.GetFileNames().Concat(new[] {commit.GetSegmentsFileName()}).ToArray(); - - var tempDir = new DirectoryInfo(_tempPath); - - //Get all files in the temp storage that don't exist in the snapshot collection, we want to remove these - var toRemove = tempDir.GetFiles() - .Select(x => x.Name) - .Except(allSnapshotFiles); - - using (var tempDirectory = new SimpleFSDirectory(tempDir)) + if (IndexWriter.IsLocked(tempDirectory) == false) { - if (IndexWriter.IsLocked(tempDirectory) == false) + foreach (var file in toRemove) { - foreach (var file in toRemove) + try { - try - { - File.Delete(Path.Combine(_tempPath, file)); - } - catch (IOException ex) - { - LogHelper.Error("Could not delete index file, could not sync from main storage", ex); - - //quit here and do not assign the lucene directory, this means that the app will now just be working from normal storage - return; - } + File.Delete(Path.Combine(_tempPath, file)); + } + catch (IOException ex) + { + LogHelper.Error("Could not delete index file, could not sync from main storage", ex); + //quit here + return false; } } - else - { - LogHelper.Warn("Cannot sync index files from main storage, the index is currently locked"); - - //quit here and do not assign the lucene directory, this means that the app will now just be working from normal storage - return; - } } - - foreach (var fileName in allSnapshotFiles.Where(f => f.IsNullOrWhiteSpace() == false)) + else { - try - { - File.Copy( - Path.Combine(basePath, "Index", fileName), - Path.Combine(_tempPath, Path.GetFileName(fileName)), true); - } - catch (IOException ex) - { - LogHelper.Error("Could not copy index file, could not sync from main storage", ex); - - //quit here and do not assign the lucene directory, this means that the app will now just be working from normal storage - return; - } + LogHelper.Warn("Cannot sync index files from main storage, the index is currently locked"); + //quit here + return false; } - } - finally + + foreach (var fileName in allSnapshotFiles.Where(f => f.IsNullOrWhiteSpace() == false)) { - Snapshotter.Release(); + try + { + File.Copy( + Path.Combine(basePath, "Index", fileName), + Path.Combine(_tempPath, Path.GetFileName(fileName)), true); + } + catch (IOException ex) + { + LogHelper.Error("Could not copy index file, could not sync from main storage", ex); + + //quit here + return false; + } } + + } + finally + { + Snapshotter.Release(); } - - //create the custom lucene directory which will keep the main and temp FS's in sync - - LuceneDirectory = new LocalTempStorageDirectory( - new DirectoryInfo(_tempPath), - baseLuceneDirectory); - } - else - { - //just return a normal lucene directory that uses the codegen folder - - LuceneDirectory = FSDirectory.Open(new DirectoryInfo(_tempPath)); } + return true; } } } diff --git a/src/UmbracoExamine/UmbracoExamine.csproj b/src/UmbracoExamine/UmbracoExamine.csproj index 49ee6c8ff6..55099b0bcd 100644 --- a/src/UmbracoExamine/UmbracoExamine.csproj +++ b/src/UmbracoExamine/UmbracoExamine.csproj @@ -122,6 +122,7 @@ + diff --git a/src/UmbracoExamine/UmbracoExamineSearcher.cs b/src/UmbracoExamine/UmbracoExamineSearcher.cs index a8eb88466b..f0fe4c8681 100644 --- a/src/UmbracoExamine/UmbracoExamineSearcher.cs +++ b/src/UmbracoExamine/UmbracoExamineSearcher.cs @@ -28,7 +28,6 @@ namespace UmbracoExamine private volatile Lucene.Net.Store.Directory _localTempDirectory; private static readonly object Locker = new object(); private string _localTempPath = null; - private bool _syncTempStorage = false; #region Constructors @@ -82,15 +81,6 @@ namespace UmbracoExamine var codegenPath = HttpRuntime.CodegenDir; _localTempPath = Path.Combine(codegenPath, configuredPath.TrimStart('~', '/').Replace("/", "\\")); } - - if (config["syncTempStorage"] != null) - { - var attemptSync = config["syncTempStorage"].TryConvertTo(); - if (attemptSync) - { - _syncTempStorage = attemptSync.Result; - } - } } } @@ -182,17 +172,9 @@ namespace UmbracoExamine { if (_localTempDirectory == null) { - if (_syncTempStorage) - { - _localTempDirectory = new LocalTempStorageDirectory( - new DirectoryInfo(_localTempPath), - base.GetLuceneDirectory()); - } - else - { - //not syncing just use a normal lucene directory - _localTempDirectory = FSDirectory.Open(new DirectoryInfo(_localTempPath)); - } + _localTempDirectory = LocalTempStorageDirectoryTracker.Current.GetDirectory( + new DirectoryInfo(_localTempPath), + base.GetLuceneDirectory()); } } }