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.Linq;
using System.Threading.Tasks;
using NodaTime;
using Squidex.Domain.Apps.Core.Contents;
@ -38,6 +39,11 @@ namespace Squidex.Domain.Apps.Entities.Contents.DomainObject
Capacity = int.MaxValue;
}
private Task LoadContext(ContentCommand command, bool optimize)
{
return context.LoadAsync(command.AppId, command.SchemaId, command, optimize);
}
protected override bool IsDeleted()
{
return Snapshot.IsDeleted;
@ -94,6 +100,7 @@ namespace Squidex.Domain.Apps.Entities.Contents.DomainObject
await CreateCore(c);
// Skip validation for singleton contents because it is published from command middleware.
if (context.Schema.SchemaDef.IsSingleton)
{
ChangeStatus(c.AsChange(Status.Published));
@ -173,7 +180,7 @@ namespace Squidex.Domain.Apps.Entities.Contents.DomainObject
if (c.DueTime > SystemClock.Instance.GetCurrentInstant())
{
ScheduleStatus(c, c.DueTime.Value);
ChangeStatusScheduled(c, c.DueTime.Value);
}
else
{
@ -251,78 +258,93 @@ namespace Squidex.Domain.Apps.Entities.Contents.DomainObject
{
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))
{
var change = GetChange(c.Status);
return;
}
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,
new ScriptVars
{
Operation = change.ToString(),
Data = data,
Status = c.Status,
StatusOld = Snapshot.EditingStatus
});
// Clone the data, so that we do not change it in cases of errors.
var data = Snapshot.Data.Clone();
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);
var dataNew = newDataFunc(Snapshot.Data);
var newData = update(Snapshot.Data);
if (!dataNew.Equals(Snapshot.Data))
if (newData.Equals(Snapshot.Data))
{
if (!c.DoNotValidate)
{
if (partial)
{
await context.ValidateInputPartialAsync(c.Data);
}
else
{
await context.ValidateInputAsync(c.Data);
}
}
return;
}
if (!c.DoNotScript)
if (!c.DoNotValidate)
{
if (partial)
{
dataNew = await context.ExecuteScriptAndTransformAsync(s => s.Update,
new ScriptVars
{
Operation = "Update",
Data = dataNew,
DataOld = Snapshot.Data,
Status = Snapshot.EditingStatus,
StatusOld = default
});
await context.ValidateInputPartialAsync(c.Data);
}
if (!c.DoNotValidate)
else
{
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)
@ -361,29 +383,29 @@ namespace Squidex.Domain.Apps.Entities.Contents.DomainObject
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
@ -406,10 +428,5 @@ namespace Squidex.Domain.Apps.Entities.Contents.DomainObject
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": {
/*
* The Google analtyics id
* The Google analytics ID.
*/
"analyticsId": "UA-99989790-2"
}

Loading…
Cancel
Save