From 18e8f096544a689e105b11a6903f5107b466d207 Mon Sep 17 00:00:00 2001 From: Shannon Date: Wed, 15 Jul 2015 17:27:01 +0200 Subject: [PATCH] BatchedDatabaseServerMessenger only exists in Web now, no reason for it to be in Core. CoreBootManager by default now uses DatabaseServerMessenger (non-batched), WebBootManager now uses BatchedDatabaseServerMessenger and is always enabled by default unless the Dist Calls setting in umbracoSettings is enabled, in that case it will revert to using the legacy batched web services messenger. --- src/Umbraco.Core/CoreBootManager.cs | 8 +- .../Sync/BatchedDatabaseServerMessenger.cs | 76 ------------------- .../Sync/DatabaseServerMessenger.cs | 8 +- src/Umbraco.Core/Umbraco.Core.csproj | 1 - .../BatchedDatabaseServerMessenger.cs | 54 ++++++++++++- src/Umbraco.Web/WebBootManager.cs | 66 +++++++++++----- 6 files changed, 104 insertions(+), 109 deletions(-) delete mode 100644 src/Umbraco.Core/Sync/BatchedDatabaseServerMessenger.cs diff --git a/src/Umbraco.Core/CoreBootManager.cs b/src/Umbraco.Core/CoreBootManager.cs index 59bda786c9..1a8f72e356 100644 --- a/src/Umbraco.Core/CoreBootManager.cs +++ b/src/Umbraco.Core/CoreBootManager.cs @@ -404,18 +404,16 @@ namespace Umbraco.Core ServerRegistrarResolver.Current = new ServerRegistrarResolver( new ConfigServerRegistrar()); - //by default (outside of the web) we'll use the default server messenger without - //supplying a username/password, this will automatically disable distributed calls - // .. we'll override this in the WebBootManager + //by default we'll use the database server messenger with default options (no callbacks), + // this will be overridden in the web startup ServerMessengerResolver.Current = new ServerMessengerResolver( - new WebServiceServerMessenger()); + new DatabaseServerMessenger(ApplicationContext, true, new DatabaseServerMessengerOptions())); MappingResolver.Current = new MappingResolver( ServiceProvider, LoggerResolver.Current.Logger, () => PluginManager.ResolveAssignedMapperTypes()); - //RepositoryResolver.Current = new RepositoryResolver( // new RepositoryFactory(ApplicationCache)); diff --git a/src/Umbraco.Core/Sync/BatchedDatabaseServerMessenger.cs b/src/Umbraco.Core/Sync/BatchedDatabaseServerMessenger.cs deleted file mode 100644 index b16caa8779..0000000000 --- a/src/Umbraco.Core/Sync/BatchedDatabaseServerMessenger.cs +++ /dev/null @@ -1,76 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using Newtonsoft.Json; -using Umbraco.Core.Models.Rdbms; -using umbraco.interfaces; - -namespace Umbraco.Core.Sync -{ - /// - /// An that works by storing messages in the database. - /// - /// - /// abstract because it needs to be inherited by a class that will - /// - trigger FlushBatch() when appropriate - /// - trigger Boot() when appropriate - /// - trigger Sync() when appropriate - /// - public abstract class BatchedDatabaseServerMessenger : DatabaseServerMessenger - { - - protected BatchedDatabaseServerMessenger(ApplicationContext appContext, bool enableDistCalls, DatabaseServerMessengerOptions options) - : base(appContext, enableDistCalls, options) - { - - } - - protected abstract ICollection GetBatch(bool ensureHttpContext); - - public void FlushBatch() - { - var batch = GetBatch(false); - if (batch == null) return; - - var instructions = batch.SelectMany(x => x.Instructions).ToArray(); - batch.Clear(); - if (instructions.Length == 0) return; - - var dto = new CacheInstructionDto - { - UtcStamp = DateTime.UtcNow, - Instructions = JsonConvert.SerializeObject(instructions, Formatting.None), - OriginIdentity = LocalIdentity - }; - - ApplicationContext.DatabaseContext.Database.Insert(dto); - } - - protected override void DeliverRemote(IEnumerable servers, ICacheRefresher refresher, MessageType messageType, IEnumerable ids = null, string json = null) - { - var idsA = ids == null ? null : ids.ToArray(); - - Type arrayType; - if (GetArrayType(idsA, out arrayType) == false) - throw new ArgumentException("All items must be of the same type, either int or Guid.", "ids"); - - BatchMessage(servers, refresher, messageType, idsA, arrayType, json); - } - - protected void BatchMessage( - IEnumerable servers, - ICacheRefresher refresher, - MessageType messageType, - IEnumerable ids = null, - Type idType = null, - string json = null) - { - var batch = GetBatch(true); - if (batch == null) - throw new Exception("Failed to get a batch."); - - batch.Add(new RefreshInstructionEnvelope(servers, refresher, - RefreshInstruction.GetInstructions(refresher, messageType, ids, idType, json))); - } - } -} diff --git a/src/Umbraco.Core/Sync/DatabaseServerMessenger.cs b/src/Umbraco.Core/Sync/DatabaseServerMessenger.cs index 4081bfc7c3..57f0907e10 100644 --- a/src/Umbraco.Core/Sync/DatabaseServerMessenger.cs +++ b/src/Umbraco.Core/Sync/DatabaseServerMessenger.cs @@ -21,15 +21,11 @@ namespace Umbraco.Core.Sync /// An that works by storing messages in the database. /// // - // abstract because it needs to be inherited by a class that will - // - trigger Boot() when appropriate - // - trigger Sync() when appropriate - // // this messenger writes ALL instructions to the database, // but only processes instructions coming from remote servers, // thus ensuring that instructions run only once // - public abstract class DatabaseServerMessenger : ServerMessengerBase + public class DatabaseServerMessenger : ServerMessengerBase { private readonly ApplicationContext _appContext; private readonly DatabaseServerMessengerOptions _options; @@ -45,7 +41,7 @@ namespace Umbraco.Core.Sync protected ApplicationContext ApplicationContext { get { return _appContext; } } - protected DatabaseServerMessenger(ApplicationContext appContext, bool distributedEnabled, DatabaseServerMessengerOptions options) + public DatabaseServerMessenger(ApplicationContext appContext, bool distributedEnabled, DatabaseServerMessengerOptions options) : base(distributedEnabled) { if (appContext == null) throw new ArgumentNullException("appContext"); diff --git a/src/Umbraco.Core/Umbraco.Core.csproj b/src/Umbraco.Core/Umbraco.Core.csproj index 045877d52f..9256e00a2c 100644 --- a/src/Umbraco.Core/Umbraco.Core.csproj +++ b/src/Umbraco.Core/Umbraco.Core.csproj @@ -1238,7 +1238,6 @@ - diff --git a/src/Umbraco.Web/BatchedDatabaseServerMessenger.cs b/src/Umbraco.Web/BatchedDatabaseServerMessenger.cs index 38de7ef3cc..1e4f94a3c0 100644 --- a/src/Umbraco.Web/BatchedDatabaseServerMessenger.cs +++ b/src/Umbraco.Web/BatchedDatabaseServerMessenger.cs @@ -1,8 +1,12 @@ using System; using System.Collections.Generic; +using System.Linq; using System.Web; +using Newtonsoft.Json; +using umbraco.interfaces; using Umbraco.Core; using Umbraco.Core.Logging; +using Umbraco.Core.Models.Rdbms; using Umbraco.Core.Sync; using Umbraco.Web.Routing; @@ -14,7 +18,7 @@ namespace Umbraco.Web /// /// This binds to appropriate umbraco events in order to trigger the Boot(), Sync() & FlushBatch() calls /// - public class BatchedDatabaseServerMessenger : Core.Sync.BatchedDatabaseServerMessenger + public class BatchedDatabaseServerMessenger : Core.Sync.DatabaseServerMessenger { public BatchedDatabaseServerMessenger(ApplicationContext appContext, bool enableDistCalls, DatabaseServerMessengerOptions options) : base(appContext, enableDistCalls, options) @@ -66,7 +70,37 @@ namespace Umbraco.Web FlushBatch(); } - protected override ICollection GetBatch(bool ensureHttpContext) + protected override void DeliverRemote(IEnumerable servers, ICacheRefresher refresher, MessageType messageType, IEnumerable ids = null, string json = null) + { + var idsA = ids == null ? null : ids.ToArray(); + + Type arrayType; + if (GetArrayType(idsA, out arrayType) == false) + throw new ArgumentException("All items must be of the same type, either int or Guid.", "ids"); + + BatchMessage(servers, refresher, messageType, idsA, arrayType, json); + } + + public void FlushBatch() + { + var batch = GetBatch(false); + if (batch == null) return; + + var instructions = batch.SelectMany(x => x.Instructions).ToArray(); + batch.Clear(); + if (instructions.Length == 0) return; + + var dto = new CacheInstructionDto + { + UtcStamp = DateTime.UtcNow, + Instructions = JsonConvert.SerializeObject(instructions, Formatting.None), + OriginIdentity = LocalIdentity + }; + + ApplicationContext.DatabaseContext.Database.Insert(dto); + } + + protected ICollection GetBatch(bool ensureHttpContext) { var httpContext = UmbracoContext.Current == null ? null : UmbracoContext.Current.HttpContext; if (httpContext == null) @@ -84,5 +118,21 @@ namespace Umbraco.Web httpContext.Items[key] = batch = new List(); return batch; } + + protected void BatchMessage( + IEnumerable servers, + ICacheRefresher refresher, + MessageType messageType, + IEnumerable ids = null, + Type idType = null, + string json = null) + { + var batch = GetBatch(true); + if (batch == null) + throw new Exception("Failed to get a batch."); + + batch.Add(new RefreshInstructionEnvelope(servers, refresher, + RefreshInstruction.GetInstructions(refresher, messageType, ids, idType, json))); + } } } \ No newline at end of file diff --git a/src/Umbraco.Web/WebBootManager.cs b/src/Umbraco.Web/WebBootManager.cs index 99bdaada4c..497056a518 100644 --- a/src/Umbraco.Web/WebBootManager.cs +++ b/src/Umbraco.Web/WebBootManager.cs @@ -329,32 +329,60 @@ namespace Umbraco.Web //set the default RenderMvcController DefaultRenderMvcControllerResolver.Current = new DefaultRenderMvcControllerResolver(typeof(RenderMvcController)); - ServerMessengerResolver.Current.SetServerMessenger(new BatchedWebServiceServerMessenger(() => + //Override the default server messenger, we need to check if the legacy dist calls is enabled, if that is the + // case, then we'll set the default messenger to be the old one, otherwise we'll set it to the db messenger + // which will always be on. + if (UmbracoConfig.For.UmbracoSettings().DistributedCall.Enabled) { - //we should not proceed to change this if the app/database is not configured since there will - // be no user, plus we don't need to have server messages sent if this is the case. - if (ApplicationContext.IsConfigured && ApplicationContext.DatabaseContext.IsDatabaseConfigured) + //set the legacy one by default - this maintains backwards compat + ServerMessengerResolver.Current.SetServerMessenger(new BatchedWebServiceServerMessenger(() => { - //disable if they are not enabled - if (UmbracoConfig.For.UmbracoSettings().DistributedCall.Enabled == false) + //we should not proceed to change this if the app/database is not configured since there will + // be no user, plus we don't need to have server messages sent if this is the case. + if (ApplicationContext.IsConfigured && ApplicationContext.DatabaseContext.IsDatabaseConfigured) { - return null; - } + //disable if they are not enabled + if (UmbracoConfig.For.UmbracoSettings().DistributedCall.Enabled == false) + { + return null; + } - try - { - var user = User.GetUser(UmbracoConfig.For.UmbracoSettings().DistributedCall.UserId); - return new System.Tuple(user.LoginName, user.GetPassword()); + try + { + var user = ApplicationContext.Services.UserService.GetUserById(UmbracoConfig.For.UmbracoSettings().DistributedCall.UserId); + return new Tuple(user.Username, user.RawPasswordValue); + } + catch (Exception e) + { + LoggerResolver.Current.Logger.Error("An error occurred trying to set the IServerMessenger during application startup", e); + return null; + } } - catch (Exception e) + LoggerResolver.Current.Logger.Warn("Could not initialize the DefaultServerMessenger, the application is not configured or the database is not configured"); + return null; + })); + } + else + { + ServerMessengerResolver.Current.SetServerMessenger(new BatchedDatabaseServerMessenger( + ApplicationContext, + true, + //Default options for web including the required callbacks to build caches + new DatabaseServerMessengerOptions + { + //These callbacks will be executed if the server has not been synced + // (i.e. it is a new server or the lastsynced.txt file has been removed) + InitializingCallbacks = new Action[] { - LoggerResolver.Current.Logger.Error("An error occurred trying to set the IServerMessenger during application startup", e); - return null; + //rebuild the xml cache file if the server is not synced + () => global::umbraco.content.Instance.RefreshContentFromDatabase(), + //rebuild indexes if the server is not synced + // NOTE: This will rebuild ALL indexes including the members, if developers want to target specific + // indexes then they can adjust this logic themselves. + () => Examine.ExamineManager.Instance.RebuildIndex() } - } - LoggerResolver.Current.Logger.Warn("Could not initialize the DefaultServerMessenger, the application is not configured or the database is not configured"); - return null; - })); + })); + } SurfaceControllerResolver.Current = new SurfaceControllerResolver( ServiceProvider, LoggerResolver.Current.Logger,