U4-7614 Allow Examine's local temp storage to exist in the current User's temp storage location - useful for Azure

This commit is contained in:
Shannon
2015-12-28 13:37:56 +01:00
parent 664aa3842d
commit c765ab9112
5 changed files with 101 additions and 9 deletions

View File

@@ -0,0 +1,30 @@
using System;
using System.Collections.Specialized;
using System.IO;
using System.Web;
using Umbraco.Core;
namespace UmbracoExamine.LocalStorage
{
/// <summary>
/// When running on Azure websites, we can use the local user's storage space
/// </summary>
public sealed class AzureLocalStorageDirectory : ILocalStorageDirectory
{
public DirectoryInfo GetLocalStorageDirectory(NameValueCollection config, string configuredPath)
{
var appDomainHash = HttpRuntime.AppDomainAppId.ToMd5();
var cachePath = Path.Combine(Environment.ExpandEnvironmentVariables("%temp%"), "LuceneDir",
//include the appdomain hash is just a safety check, for example if a website is moved from worker A to worker B and then back
// to worker A again, in theory the %temp% folder should already be empty but we really want to make sure that its not
// utilizing an old index
appDomainHash,
//ensure the temp path is consistent with the configured path location
configuredPath.TrimStart('~', '/').Replace("/", "\\"));
var azureDir = new DirectoryInfo(cachePath);
if (azureDir.Exists == false)
azureDir.Create();
return azureDir;
}
}
}

View File

@@ -0,0 +1,25 @@
using System.Collections.Specialized;
using System.IO;
using System.Web;
namespace UmbracoExamine.LocalStorage
{
/// <summary>
/// Use the ASP.Net CodeGen folder to store the index files
/// </summary>
/// <remarks>
/// This is the default implementation - but it comes with it's own limitations - the CodeGen folder is cleared whenever new
/// DLLs are changed in the /bin folder (among other circumstances) which means the index would be re-synced (or rebuilt) there.
/// </remarks>
public sealed class CodeGenLocalStorageDirectory : ILocalStorageDirectory
{
public DirectoryInfo GetLocalStorageDirectory(NameValueCollection config, string configuredPath)
{
var codegenPath = HttpRuntime.CodegenDir;
var path = Path.Combine(codegenPath,
//ensure the temp path is consistent with the configured path location
configuredPath.TrimStart('~', '/').Replace("/", "\\"));
return new DirectoryInfo(path);
}
}
}

View File

@@ -0,0 +1,13 @@
using System.Collections.Specialized;
using System.IO;
namespace UmbracoExamine.LocalStorage
{
/// <summary>
/// Used to resolve the local storage folder
/// </summary>
public interface ILocalStorageDirectory
{
DirectoryInfo GetLocalStorageDirectory(NameValueCollection config, string configuredPath);
}
}

View File

@@ -4,6 +4,7 @@ using System.IO;
using System.Linq;
using System.Threading;
using System.Web;
using System.Web.Compilation;
using Examine.LuceneEngine;
using Lucene.Net.Analysis;
using Lucene.Net.Index;
@@ -42,9 +43,29 @@ namespace UmbracoExamine.LocalStorage
public void Initialize(NameValueCollection config, string configuredPath, FSDirectory baseLuceneDirectory, Analyzer analyzer, LocalStorageType localStorageType)
{
var codegenPath = HttpRuntime.CodegenDir;
ILocalStorageDirectory localStorateDir = new CodeGenLocalStorageDirectory();
if (config["tempStorageDirectory"] != null)
{
//try to get the type
var dirType = BuildManager.GetType(config["tempStorageDirectory"], false);
if (dirType != null)
{
try
{
localStorateDir = (ILocalStorageDirectory)Activator.CreateInstance(dirType);
}
catch (Exception ex)
{
LogHelper.Error<LocalTempStorageIndexer>(
string.Format("Could not create a temp storage location of type {0}, reverting to use the " + typeof (CodeGenLocalStorageDirectory).FullName, dirType),
ex);
}
}
}
TempPath = Path.Combine(codegenPath, configuredPath.TrimStart('~', '/').Replace("/", "\\"));
var tempPath = localStorateDir.GetLocalStorageDirectory(config, configuredPath);
if (tempPath == null) throw new InvalidOperationException("Could not resolve a temp location from the " + localStorateDir.GetType() + " specified");
TempPath = tempPath.FullName;
switch (localStorageType)
{
@@ -101,7 +122,7 @@ namespace UmbracoExamine.LocalStorage
baseLuceneDirectory,
//Disable mirrored index, we're kind of screwed here only use master index
true);
}
}
break;
case LocalStorageType.LocalOnly:
@@ -234,7 +255,7 @@ namespace UmbracoExamine.LocalStorage
IndexWriter.Unlock(dir);
}
if (IndexWriter.IsLocked(dir) == false) return Attempt.Succeed(true);
if (IndexWriter.IsLocked(dir) == false) return Attempt.Succeed(true);
LogHelper.Info<LocalTempStorageIndexer>("Could not acquire directory lock for {0} writer, retrying ....", dir.ToString);
return Attempt<bool>.Fail();
}, 5, TimeSpan.FromSeconds(1));
@@ -267,7 +288,7 @@ namespace UmbracoExamine.LocalStorage
{
//NOTE: To date I've not seen this error occur
using (writerAttempt.Result.GetReader())
{
{
}
}
catch (Exception ex)
@@ -275,14 +296,14 @@ namespace UmbracoExamine.LocalStorage
writerAttempt.Result.Dispose();
LogHelper.Error<LocalTempStorageIndexer>(
string.Format("Could not open an index reader, {0} is empty or corrupt... attempting to clear index files in master folder", configuredPath),
string.Format("Could not open an index reader, {0} is empty or corrupt... attempting to clear index files in master folder", configuredPath),
ex);
if (ClearLuceneDirFiles(baseLuceneDirectory) == false)
{
//hrm, not much we can do in this situation, but this shouldn't happen
LogHelper.Error<LocalTempStorageIndexer>("Could not open an index reader, index is corrupt.", ex);
return InitializeDirectoryFlags.FailedCorrupt;
LogHelper.Error<LocalTempStorageIndexer>("Could not open an index reader, index is corrupt.", ex);
return InitializeDirectoryFlags.FailedCorrupt;
}
//the main index is now blank, we'll proceed as normal with a new empty index...
@@ -338,7 +359,7 @@ namespace UmbracoExamine.LocalStorage
}
LogHelper.Debug<LocalTempStorageIndexer>("Could not delete non synced index file file, index sync will continue but old index files will remain - this shouldn't affect indexing/searching operations. {0}", () => ex.ToString());
}
}
}

View File

@@ -124,6 +124,9 @@
<Compile Include="ExamineHelper.cs" />
<Compile Include="IndexTypes.cs" />
<Compile Include="LegacyLibrary.cs" />
<Compile Include="LocalStorage\AzureLocalStorageDirectory.cs" />
<Compile Include="LocalStorage\CodeGenLocalStorageDirectory.cs" />
<Compile Include="LocalStorage\ILocalStorageDirectory.cs" />
<Compile Include="LocalStorage\LocalStorageType.cs" />
<Compile Include="LocalStorage\LocalTempStorageDirectory.cs" />
<Compile Include="LocalStorage\LocalTempStorageDirectoryTracker.cs" />