using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using Newtonsoft.Json;
using NPoco;
using Umbraco.Core;
using Umbraco.Core.Cache;
using Umbraco.Core.Sync;
using Umbraco.Web.Routing;
using Umbraco.Core.Logging;
using Umbraco.Core.Persistence;
using Umbraco.Core.Persistence.Dtos;
using Umbraco.Core.Scoping;
namespace Umbraco.Web
{
///
/// An implementation that works by storing messages in the database.
///
///
/// This binds to appropriate umbraco events in order to trigger the Boot(), Sync() & FlushBatch() calls
///
public class BatchedDatabaseServerMessenger : DatabaseServerMessenger
{
private readonly IUmbracoDatabaseFactory _databaseFactory;
public BatchedDatabaseServerMessenger(
IRuntimeState runtime, IUmbracoDatabaseFactory databaseFactory, IScopeProvider scopeProvider, ISqlContext sqlContext, ILogger logger, ProfilingLogger proflog,
bool enableDistCalls, DatabaseServerMessengerOptions options)
: base(runtime, scopeProvider, sqlContext, logger, proflog, enableDistCalls, options)
{
_databaseFactory = databaseFactory;
}
// invoked by BatchedDatabaseServerMessengerStartup which is an ApplicationEventHandler
// with default "ShouldExecute", so that method will run if app IsConfigured and database
// context IsDatabaseConfigured - we still want to check CanConnect though to be safe
internal void Startup()
{
UmbracoModule.EndRequest += UmbracoModule_EndRequest;
UmbracoModule.RouteAttempt += UmbracoModule_RouteAttempt;
if (_databaseFactory.CanConnect == false)
{
Logger.Warn(
"Cannot connect to the database, distributed calls will not be enabled for this server.");
}
else
{
Boot();
}
}
private void UmbracoModule_RouteAttempt(object sender, RoutableAttemptEventArgs e)
{
// as long as umbraco is ready & configured, sync
switch (e.Outcome)
{
case EnsureRoutableOutcome.IsRoutable:
case EnsureRoutableOutcome.NotDocumentRequest:
case EnsureRoutableOutcome.NoContent:
Sync();
break;
//case EnsureRoutableOutcome.NotReady:
//case EnsureRoutableOutcome.NotConfigured:
//default:
// break;
}
}
private void UmbracoModule_EndRequest(object sender, UmbracoRequestEventArgs e)
{
// will clear the batch - will remain in HttpContext though - that's ok
FlushBatch();
}
protected override void DeliverRemote(IEnumerable servers, ICacheRefresher refresher, MessageType messageType, IEnumerable