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.

This commit is contained in:
Shannon
2015-07-15 17:27:01 +02:00
parent 85ebcadcdd
commit 18e8f09654
6 changed files with 104 additions and 109 deletions

View File

@@ -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));

View File

@@ -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
{
/// <summary>
/// An <see cref="IServerMessenger"/> that works by storing messages in the database.
/// </summary>
/// <remarks>
/// abstract because it needs to be inherited by a class that will
/// - trigger FlushBatch() when appropriate
/// - trigger Boot() when appropriate
/// - trigger Sync() when appropriate
/// </remarks>
public abstract class BatchedDatabaseServerMessenger : DatabaseServerMessenger
{
protected BatchedDatabaseServerMessenger(ApplicationContext appContext, bool enableDistCalls, DatabaseServerMessengerOptions options)
: base(appContext, enableDistCalls, options)
{
}
protected abstract ICollection<RefreshInstructionEnvelope> 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<IServerAddress> servers, ICacheRefresher refresher, MessageType messageType, IEnumerable<object> 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<IServerAddress> servers,
ICacheRefresher refresher,
MessageType messageType,
IEnumerable<object> 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)));
}
}
}

View File

@@ -21,15 +21,11 @@ namespace Umbraco.Core.Sync
/// An <see cref="IServerMessenger"/> that works by storing messages in the database.
/// </summary>
//
// 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");

View File

@@ -1238,7 +1238,6 @@
<Compile Include="Strategies\RelateOnTrashHandler.cs" />
<Compile Include="Strings\ContentBaseExtensions.cs" />
<Compile Include="Strings\Diff.cs" />
<Compile Include="Sync\BatchedDatabaseServerMessenger.cs" />
<Compile Include="Sync\BatchedWebServiceServerMessenger.cs" />
<Compile Include="Sync\CurrentServerEnvironmentStatus.cs" />
<Compile Include="Sync\DatabaseServerMessenger.cs" />

View File

@@ -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
/// <remarks>
/// This binds to appropriate umbraco events in order to trigger the Boot(), Sync() & FlushBatch() calls
/// </remarks>
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<RefreshInstructionEnvelope> GetBatch(bool ensureHttpContext)
protected override void DeliverRemote(IEnumerable<IServerAddress> servers, ICacheRefresher refresher, MessageType messageType, IEnumerable<object> 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<RefreshInstructionEnvelope> 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<RefreshInstructionEnvelope>();
return batch;
}
protected void BatchMessage(
IEnumerable<IServerAddress> servers,
ICacheRefresher refresher,
MessageType messageType,
IEnumerable<object> 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)));
}
}
}

View File

@@ -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<string, string>(user.LoginName, user.GetPassword());
try
{
var user = ApplicationContext.Services.UserService.GetUserById(UmbracoConfig.For.UmbracoSettings().DistributedCall.UserId);
return new Tuple<string, string>(user.Username, user.RawPasswordValue);
}
catch (Exception e)
{
LoggerResolver.Current.Logger.Error<WebBootManager>("An error occurred trying to set the IServerMessenger during application startup", e);
return null;
}
}
catch (Exception e)
LoggerResolver.Current.Logger.Warn<WebBootManager>("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<WebBootManager>("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<WebBootManager>("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,