DatabaseServerMessenger - sync only if MainDom

This commit is contained in:
Stephan
2015-07-03 15:33:07 +02:00
parent d386c069ee
commit 7bf28a20e7

View File

@@ -4,6 +4,7 @@ using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Threading;
using System.Web;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
@@ -32,11 +33,13 @@ namespace Umbraco.Core.Sync
{
private readonly ApplicationContext _appContext;
private readonly DatabaseServerMessengerOptions _options;
private readonly object _lock = new object();
private readonly ManualResetEvent _syncIdle;
private readonly object _locko = new object();
private int _lastId = -1;
private volatile bool _syncing;
private DateTime _lastSync;
private bool _initialized;
private bool _syncing;
private bool _released;
protected ApplicationContext ApplicationContext { get { return _appContext; } }
@@ -49,6 +52,8 @@ namespace Umbraco.Core.Sync
_appContext = appContext;
_options = options;
_lastSync = DateTime.UtcNow;
_syncIdle = new ManualResetEvent(true);
}
#region Messenger
@@ -98,6 +103,24 @@ namespace Umbraco.Core.Sync
/// </remarks>
protected void Boot()
{
// weight:10, must release *before* the facade service, because once released
// the service will *not* be able to properly handle our notifications anymore
const int weight = 10;
var registered = ApplicationContext.MainDom.Register(
() =>
{
lock (_locko)
{
_released = true; // no more syncs
}
_syncIdle.WaitOne(); // wait for pending sync
},
weight);
if (registered == false)
return;
ReadLastSynced();
Initialize();
}
@@ -111,26 +134,31 @@ namespace Umbraco.Core.Sync
/// </remarks>
private void Initialize()
{
if (_lastId < 0) // never synced before
lock (_locko)
{
// we haven't synced - in this case we aren't going to sync the whole thing, we will assume this is a new
// server and it will need to rebuild it's own caches, eg Lucene or the xml cache file.
LogHelper.Warn<DatabaseServerMessenger>("No last synced Id found, this generally means this is a new server/install. The server will rebuild its caches and indexes and then adjust it's last synced id to the latest found in the database and will start maintaining cache updates based on that id");
if (_released) return;
// go get the last id in the db and store it
// note: do it BEFORE initializing otherwise some instructions might get lost
// when doing it before, some instructions might run twice - not an issue
var lastId = _appContext.DatabaseContext.Database.ExecuteScalar<int>("SELECT MAX(id) FROM umbracoCacheInstruction");
if (lastId > 0)
SaveLastSynced(lastId);
if (_lastId < 0) // never synced before
{
// we haven't synced - in this case we aren't going to sync the whole thing, we will assume this is a new
// server and it will need to rebuild it's own caches, eg Lucene or the xml cache file.
LogHelper.Warn<DatabaseServerMessenger>("No last synced Id found, this generally means this is a new server/install. The server will rebuild its caches and indexes and then adjust it's last synced id to the latest found in the database and will start maintaining cache updates based on that id");
// execute initializing callbacks
if (_options.InitializingCallbacks != null)
foreach (var callback in _options.InitializingCallbacks)
callback();
// go get the last id in the db and store it
// note: do it BEFORE initializing otherwise some instructions might get lost
// when doing it before, some instructions might run twice - not an issue
var lastId = _appContext.DatabaseContext.Database.ExecuteScalar<int>("SELECT MAX(id) FROM umbracoCacheInstruction");
if (lastId > 0)
SaveLastSynced(lastId);
// execute initializing callbacks
if (_options.InitializingCallbacks != null)
foreach (var callback in _options.InitializingCallbacks)
callback();
}
_initialized = true;
}
_initialized = true;
}
/// <summary>
@@ -138,25 +166,34 @@ namespace Umbraco.Core.Sync
/// </summary>
protected void Sync()
{
if ((DateTime.UtcNow - _lastSync).Seconds <= _options.ThrottleSeconds)
return;
if (_syncing) return;
lock (_lock)
lock (_locko)
{
if (_syncing) return;
if (_syncing)
return;
_syncing = true; // lock other threads out
if (_released)
return;
if ((DateTime.UtcNow - _lastSync).Seconds <= _options.ThrottleSeconds)
return;
_syncing = true;
_syncIdle.Reset();
_lastSync = DateTime.UtcNow;
}
try
{
using (DisposableTimer.DebugDuration<DatabaseServerMessenger>("Syncing from database..."))
{
ProcessDatabaseInstructions();
PruneOldInstructions();
}
_syncing = false; // release
}
finally
{
_syncing = false;
_syncIdle.Set();
}
}