Browse Source

Reduce the number of events. (#664)

* Reduce the number of events.

* Minor code fix.

* Add a few comments.

* More comments.

* Fix spelling error.

* Skip equal test.

* Temp.
pull/666/head
Sebastian Stehle 5 years ago
committed by GitHub
parent
commit
0bc062e514
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 145
      backend/src/Squidex.Domain.Apps.Entities/Contents/DomainObject/ContentDomainObject.cs
  2. 2
      backend/src/Squidex/appsettings.json

145
backend/src/Squidex.Domain.Apps.Entities/Contents/DomainObject/ContentDomainObject.cs

@ -6,6 +6,7 @@
// ========================================================================== // ==========================================================================
using System; using System;
using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using NodaTime; using NodaTime;
using Squidex.Domain.Apps.Core.Contents; using Squidex.Domain.Apps.Core.Contents;
@ -38,6 +39,11 @@ namespace Squidex.Domain.Apps.Entities.Contents.DomainObject
Capacity = int.MaxValue; Capacity = int.MaxValue;
} }
private Task LoadContext(ContentCommand command, bool optimize)
{
return context.LoadAsync(command.AppId, command.SchemaId, command, optimize);
}
protected override bool IsDeleted() protected override bool IsDeleted()
{ {
return Snapshot.IsDeleted; return Snapshot.IsDeleted;
@ -94,6 +100,7 @@ namespace Squidex.Domain.Apps.Entities.Contents.DomainObject
await CreateCore(c); await CreateCore(c);
// Skip validation for singleton contents because it is published from command middleware.
if (context.Schema.SchemaDef.IsSingleton) if (context.Schema.SchemaDef.IsSingleton)
{ {
ChangeStatus(c.AsChange(Status.Published)); ChangeStatus(c.AsChange(Status.Published));
@ -173,7 +180,7 @@ namespace Squidex.Domain.Apps.Entities.Contents.DomainObject
if (c.DueTime > SystemClock.Instance.GetCurrentInstant()) if (c.DueTime > SystemClock.Instance.GetCurrentInstant())
{ {
ScheduleStatus(c, c.DueTime.Value); ChangeStatusScheduled(c, c.DueTime.Value);
} }
else else
{ {
@ -251,78 +258,93 @@ namespace Squidex.Domain.Apps.Entities.Contents.DomainObject
{ {
await GuardContent.CanChangeStatus(c, Snapshot, context.Workflow, context.Repository, context.Schema); await GuardContent.CanChangeStatus(c, Snapshot, context.Workflow, context.Repository, context.Schema);
if (c.Status != Snapshot.Status) if (c.Status == Snapshot.Status)
{ {
if (!c.DoNotScript && context.HasScript(c => c.Change)) return;
{ }
var change = GetChange(c.Status);
var data = Snapshot.Data.Clone(); // Check for script to skip cloning if no script configured.
if (!c.DoNotScript && context.HasScript(c => c.Change))
{
var change = GetChange(c.Status);
var newData = await context.ExecuteScriptAndTransformAsync(s => s.Change, // Clone the data, so that we do not change it in cases of errors.
new ScriptVars var data = Snapshot.Data.Clone();
{
Operation = change.ToString(),
Data = data,
Status = c.Status,
StatusOld = Snapshot.EditingStatus
});
if (!newData.Equals(Snapshot.Data)) var newData = await context.ExecuteScriptAndTransformAsync(s => s.Change,
new ScriptVars
{ {
Update(c, newData); Operation = change.ToString(),
} Data = data,
} Status = c.Status,
StatusOld = Snapshot.EditingStatus
});
if (!c.DoNotValidate && c.Status == Status.Published) // Just update the previous data event to improve performance and add less events.
var previousEvent =
GetUncomittedEvents().Select(x => x.Payload)
.OfType<ContentDataCommand>().FirstOrDefault();
if (previousEvent != null)
{
previousEvent.Data = newData;
}
else if (!newData.Equals(Snapshot.Data))
{ {
await context.ValidateOnPublishAsync(Snapshot.Data); Update(c, newData);
} }
}
ChangeStatus(c); if (!c.DoNotValidate && c.Status == Status.Published)
{
await context.ValidateOnPublishAsync(Snapshot.Data);
} }
ChangeStatus(c);
} }
private async Task UpdateCore(UpdateContent c, Func<ContentData, ContentData> newDataFunc, bool partial) private async Task UpdateCore(UpdateContent c, Func<ContentData, ContentData> update, bool partial)
{ {
await GuardContent.CanUpdate(c, Snapshot, context.Workflow); await GuardContent.CanUpdate(c, Snapshot, context.Workflow);
var dataNew = newDataFunc(Snapshot.Data); var newData = update(Snapshot.Data);
if (!dataNew.Equals(Snapshot.Data)) if (newData.Equals(Snapshot.Data))
{ {
if (!c.DoNotValidate) return;
{ }
if (partial)
{
await context.ValidateInputPartialAsync(c.Data);
}
else
{
await context.ValidateInputAsync(c.Data);
}
}
if (!c.DoNotScript) if (!c.DoNotValidate)
{
if (partial)
{ {
dataNew = await context.ExecuteScriptAndTransformAsync(s => s.Update, await context.ValidateInputPartialAsync(c.Data);
new ScriptVars
{
Operation = "Update",
Data = dataNew,
DataOld = Snapshot.Data,
Status = Snapshot.EditingStatus,
StatusOld = default
});
} }
else
if (!c.DoNotValidate)
{ {
await context.ValidateContentAsync(dataNew); await context.ValidateInputAsync(c.Data);
} }
}
Update(c, dataNew); if (!c.DoNotScript)
{
newData = await context.ExecuteScriptAndTransformAsync(s => s.Update,
new ScriptVars
{
Operation = "Update",
Data = newData,
DataOld = Snapshot.Data,
Status = Snapshot.EditingStatus,
StatusOld = default
});
}
if (!c.DoNotValidate)
{
await context.ValidateContentAsync(newData);
} }
Update(c, newData);
} }
private async Task DeleteCore(DeleteContent c) private async Task DeleteCore(DeleteContent c)
@ -361,29 +383,29 @@ namespace Squidex.Domain.Apps.Entities.Contents.DomainObject
Raise(command, new ContentStatusChanged { Change = GetChange(command.Status) }); Raise(command, new ContentStatusChanged { Change = GetChange(command.Status) });
} }
private void CreateDraft(CreateContentDraft command, Status status) private void ChangeStatusScheduled(ChangeContentStatus command, Instant dueTime)
{ {
Raise(command, new ContentDraftCreated { Status = status }); Raise(command, new ContentStatusScheduled { DueTime = dueTime });
} }
private void Delete(DeleteContent command) private void CancelChangeStatus(ChangeContentStatus command)
{ {
Raise(command, new ContentDeleted()); Raise(command, new ContentSchedulingCancelled());
} }
private void DeleteDraft(DeleteContentDraft command) private void CreateDraft(CreateContentDraft command, Status status)
{ {
Raise(command, new ContentDraftDeleted()); Raise(command, new ContentDraftCreated { Status = status });
} }
private void CancelChangeStatus(ChangeContentStatus command) private void Delete(DeleteContent command)
{ {
Raise(command, new ContentSchedulingCancelled()); Raise(command, new ContentDeleted());
} }
private void ScheduleStatus(ChangeContentStatus command, Instant dueTime) private void DeleteDraft(DeleteContentDraft command)
{ {
Raise(command, new ContentStatusScheduled { DueTime = dueTime }); Raise(command, new ContentDraftDeleted());
} }
private void Raise<T, TEvent>(T command, TEvent @event) where T : class where TEvent : AppEvent private void Raise<T, TEvent>(T command, TEvent @event) where T : class where TEvent : AppEvent
@ -406,10 +428,5 @@ namespace Squidex.Domain.Apps.Entities.Contents.DomainObject
return StatusChange.Change; return StatusChange.Change;
} }
} }
private Task LoadContext(ContentCommand command, bool optimize)
{
return context.LoadAsync(command.AppId, command.SchemaId, command, optimize);
}
} }
} }

2
backend/src/Squidex/appsettings.json

@ -175,7 +175,7 @@
"google": { "google": {
/* /*
* The Google analtyics id * The Google analytics ID.
*/ */
"analyticsId": "UA-99989790-2" "analyticsId": "UA-99989790-2"
} }

Loading…
Cancel
Save