Merge branch dev-v8 into temp-u4-8497

This commit is contained in:
Stephan
2016-07-20 12:38:57 +02:00
400 changed files with 13964 additions and 4002 deletions

View File

@@ -35,6 +35,7 @@ namespace Umbraco.Core.Sync
private readonly ILogger _logger;
private int _lastId = -1;
private DateTime _lastSync;
private DateTime _lastPruned;
private bool _initialized;
private bool _syncing;
private bool _released;
@@ -50,7 +51,7 @@ namespace Umbraco.Core.Sync
_appContext = appContext;
_options = options;
_lastSync = DateTime.UtcNow;
_lastPruned = _lastSync = DateTime.UtcNow;
_syncIdle = new ManualResetEvent(true);
_profilingLogger = appContext.ProfilingLogger;
_logger = appContext.ProfilingLogger.Logger;
@@ -213,6 +214,12 @@ namespace Umbraco.Core.Sync
using (_profilingLogger.DebugDuration<DatabaseServerMessenger>("Syncing from database..."))
{
ProcessDatabaseInstructions();
if ((DateTime.UtcNow - _lastPruned).TotalSeconds <= _options.PruneThrottleSeconds)
return;
_lastPruned = _lastSync;
switch (_appContext.GetCurrentServerRole())
{
case ServerRole.Single:
@@ -235,6 +242,9 @@ namespace Umbraco.Core.Sync
/// <remarks>
/// Thread safety: this is NOT thread safe. Because it is NOT meant to run multi-threaded.
/// </remarks>
/// <returns>
/// Returns the number of processed instructions
/// </returns>
private void ProcessDatabaseInstructions()
{
// NOTE
@@ -313,50 +323,53 @@ namespace Umbraco.Core.Sync
private void PruneOldInstructions()
{
var pruneDate = DateTime.UtcNow.AddDays(-_options.DaysToRetainInstructions);
var sqlSyntax = _appContext.DatabaseContext.SqlSyntax;
//NOTE: this query could work on SQL server and MySQL:
/*
SELECT id
FROM umbracoCacheInstruction
WHERE utcStamp < getdate()
AND id <> (SELECT MAX(id) FROM umbracoCacheInstruction)
*/
// However, this will not work on SQLCE and in fact it will be slower than the query we are
// using if the SQL server doesn't perform it's own query optimizations (i.e. since the above
// query could actually execute a sub query for every row found). So we've had to go with an
// inner join which is faster and works on SQLCE but it's uglier to read.
// using 2 queries is faster than convoluted joins
var deleteQuery = new Sql().Select("cacheIns.id")
.From("umbracoCacheInstruction cacheIns")
.InnerJoin("(SELECT MAX(id) id FROM umbracoCacheInstruction) tMax")
.On("cacheIns.id <> tMax.id")
.Where("cacheIns.utcStamp < @pruneDate", new {pruneDate = pruneDate});
var maxId = _appContext.DatabaseContext.Database.ExecuteScalar<int>("SELECT MAX(id) FROM umbracoCacheInstruction;");
var deleteSql = sqlSyntax.GetDeleteSubquery(
"umbracoCacheInstruction",
"id",
deleteQuery);
var delete = new Sql().Append(@"DELETE FROM umbracoCacheInstruction WHERE utcStamp < @pruneDate AND id < @maxId",
new { pruneDate, maxId });
_appContext.DatabaseContext.Database.Execute(deleteSql);
_appContext.DatabaseContext.Database.Execute(delete);
}
/// <summary>
/// Ensure that the last instruction that was processed is still in the database.
/// </summary>
/// <remarks>If the last instruction is not in the database anymore, then the messenger
/// <remarks>
/// If the last instruction is not in the database anymore, then the messenger
/// should not try to process any instructions, because some instructions might be lost,
/// and it should instead cold-boot.</remarks>
/// and it should instead cold-boot.
/// However, if the last synced instruction id is '0' and there are '0' records, then this indicates
/// that it's a fresh site and no user actions have taken place, in this circumstance we do not want to cold
/// boot. See: http://issues.umbraco.org/issue/U4-8627
/// </remarks>
private void EnsureInstructions()
{
var sql = _appContext.DatabaseContext.Sql().SelectAll()
.From<CacheInstructionDto>()
.Where<CacheInstructionDto>(dto => dto.Id == _lastId);
if (_lastId == 0)
{
var sql = _appContext.DatabaseContext.Sql().Select("COUNT(*)")
.From<CacheInstructionDto>();
var dtos = _appContext.DatabaseContext.Database.Fetch<CacheInstructionDto>(sql);
var count = _appContext.DatabaseContext.Database.ExecuteScalar<int>(sql);
if (dtos.Count == 0)
_lastId = -1;
//if there are instructions but we haven't synced, then a cold boot is necessary
if (count > 0)
_lastId = -1;
}
else
{
var sql = _appContext.DatabaseContext.Sql().SelectAll()
.From<CacheInstructionDto>()
.Where<CacheInstructionDto>(dto => dto.Id == _lastId);
var dtos = _appContext.DatabaseContext.Database.Fetch<CacheInstructionDto>(sql);
//if the last synced instruction is not found in the db, then a cold boot is necessary
if (dtos.Count == 0)
_lastId = -1;
}
}
/// <summary>
@@ -399,7 +412,7 @@ namespace Umbraco.Core.Sync
/// <para>Practically, all we really need is the guid, the other infos are here for information
/// and debugging purposes.</para>
/// </remarks>
protected readonly static string LocalIdentity = NetworkHelper.MachineName // eg DOMAIN\SERVER
protected static readonly string LocalIdentity = NetworkHelper.MachineName // eg DOMAIN\SERVER
+ "/" + HttpRuntime.AppDomainAppId // eg /LM/S3SVC/11/ROOT
+ " [P" + Process.GetCurrentProcess().Id // eg 1234
+ "/D" + AppDomain.CurrentDomain.Id // eg 22