Merge branch dev-v8 into temp-u4-8497
This commit is contained in:
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user