Browse Source

Performance improvements:

1. Caching for app tags
2. Caching for available languages.
pull/382/head
Sebastian 7 years ago
parent
commit
8476e5bfc0
  1. 6
      src/Squidex.Domain.Apps.Core.Operations/Tags/ITagService.cs
  2. 2
      src/Squidex.Domain.Apps.Core.Operations/Tags/TagsExport.cs
  3. 26
      src/Squidex.Domain.Apps.Core.Operations/Tags/TagsSet.cs
  4. 2
      src/Squidex.Domain.Apps.Entities/Assets/BackupAssets.cs
  5. 6
      src/Squidex.Domain.Apps.Entities/Tags/GrainTagService.cs
  6. 6
      src/Squidex.Domain.Apps.Entities/Tags/ITagGrain.cs
  7. 12
      src/Squidex.Domain.Apps.Entities/Tags/TagGrain.cs
  8. 6
      src/Squidex/Areas/Api/Controllers/Assets/AssetsController.cs
  9. 22
      src/Squidex/app/shared/state/languages.state.ts
  10. 2
      tests/Squidex.Domain.Apps.Entities.Tests/Tags/GrainTagServiceTests.cs
  11. 2
      tests/Squidex.Domain.Apps.Entities.Tests/Tags/TagGrainTests.cs

6
src/Squidex.Domain.Apps.Core.Operations/Tags/ITagService.cs

@ -19,11 +19,11 @@ namespace Squidex.Domain.Apps.Core.Tags
Task<Dictionary<string, string>> DenormalizeTagsAsync(Guid appId, string group, HashSet<string> ids);
Task<Dictionary<string, int>> GetTagsAsync(Guid appId, string group);
Task<TagsSet> GetTagsAsync(Guid appId, string group);
Task<TagSet> GetExportableTagsAsync(Guid appId, string group);
Task<TagsExport> GetExportableTagsAsync(Guid appId, string group);
Task RebuildTagsAsync(Guid appId, string group, TagSet tags);
Task RebuildTagsAsync(Guid appId, string group, TagsExport tags);
Task ClearAsync(Guid appId, string group);
}

2
src/Squidex.Domain.Apps.Core.Operations/Tags/TagSet.cs → src/Squidex.Domain.Apps.Core.Operations/Tags/TagsExport.cs

@ -9,7 +9,7 @@ using System.Collections.Generic;
namespace Squidex.Domain.Apps.Core.Tags
{
public sealed class TagSet : Dictionary<string, Tag>
public sealed class TagsExport : Dictionary<string, Tag>
{
}
}

26
src/Squidex.Domain.Apps.Core.Operations/Tags/TagsSet.cs

@ -0,0 +1,26 @@
// ==========================================================================
// Squidex Headless CMS
// ==========================================================================
// Copyright (c) Squidex UG (haftungsbeschraenkt)
// All rights reserved. Licensed under the MIT license.
// ==========================================================================
using System.Collections.Generic;
namespace Squidex.Domain.Apps.Core.Tags
{
public sealed class TagsSet : Dictionary<string, int>
{
public long Version { get; set; }
public TagsSet()
{
}
public TagsSet(IDictionary<string, int> tags, long version)
: base(tags)
{
Version = version;
}
}
}

2
src/Squidex.Domain.Apps.Entities/Assets/BackupAssets.cs

@ -82,7 +82,7 @@ namespace Squidex.Domain.Apps.Entities.Assets
private async Task RestoreTagsAsync(Guid appId, BackupReader reader)
{
var tags = await reader.ReadJsonAttachmentAsync<TagSet>(TagsFile);
var tags = await reader.ReadJsonAttachmentAsync<TagsExport>(TagsFile);
await tagService.RebuildTagsAsync(appId, TagGroups.Assets, tags);
}

6
src/Squidex.Domain.Apps.Entities/Tags/GrainTagService.cs

@ -45,17 +45,17 @@ namespace Squidex.Domain.Apps.Entities.Tags
return GetGrain(appId, group).DenormalizeTagsAsync(ids);
}
public Task<Dictionary<string, int>> GetTagsAsync(Guid appId, string group)
public Task<TagsSet> GetTagsAsync(Guid appId, string group)
{
return GetGrain(appId, group).GetTagsAsync();
}
public Task<TagSet> GetExportableTagsAsync(Guid appId, string group)
public Task<TagsExport> GetExportableTagsAsync(Guid appId, string group)
{
return GetGrain(appId, group).GetExportableTagsAsync();
}
public Task RebuildTagsAsync(Guid appId, string group, TagSet tags)
public Task RebuildTagsAsync(Guid appId, string group, TagsExport tags)
{
return GetGrain(appId, group).RebuildAsync(tags);
}

6
src/Squidex.Domain.Apps.Entities/Tags/ITagGrain.cs

@ -20,12 +20,12 @@ namespace Squidex.Domain.Apps.Entities.Tags
Task<Dictionary<string, string>> DenormalizeTagsAsync(HashSet<string> ids);
Task<Dictionary<string, int>> GetTagsAsync();
Task<TagsSet> GetTagsAsync();
Task<TagSet> GetExportableTagsAsync();
Task<TagsExport> GetExportableTagsAsync();
Task ClearAsync();
Task RebuildAsync(TagSet tags);
Task RebuildAsync(TagsExport tags);
}
}

12
src/Squidex.Domain.Apps.Entities/Tags/TagGrain.cs

@ -20,7 +20,7 @@ namespace Squidex.Domain.Apps.Entities.Tags
[CollectionName("Index_Tags")]
public sealed class GrainState
{
public TagSet Tags { get; set; } = new TagSet();
public TagsExport Tags { get; set; } = new TagsExport();
}
public TagGrain(IStore<string> store)
@ -33,7 +33,7 @@ namespace Squidex.Domain.Apps.Entities.Tags
return ClearStateAsync();
}
public Task RebuildAsync(TagSet tags)
public Task RebuildAsync(TagsExport tags)
{
State.Tags = tags;
@ -132,12 +132,14 @@ namespace Squidex.Domain.Apps.Entities.Tags
return Task.FromResult(result);
}
public Task<Dictionary<string, int>> GetTagsAsync()
public Task<TagsSet> GetTagsAsync()
{
return Task.FromResult(State.Tags.Values.ToDictionary(x => x.Name, x => x.Count));
var tags = State.Tags.Values.ToDictionary(x => x.Name, x => x.Count);
return Task.FromResult(new TagsSet(tags, Persistence.Version));
}
public Task<TagSet> GetExportableTagsAsync()
public Task<TagsExport> GetExportableTagsAsync()
{
return Task.FromResult(State.Tags);
}

6
src/Squidex/Areas/Api/Controllers/Assets/AssetsController.cs

@ -77,9 +77,11 @@ namespace Squidex.Areas.Api.Controllers.Assets
[ApiCosts(1)]
public async Task<IActionResult> GetTags(string app)
{
var response = await tagService.GetTagsAsync(AppId, TagGroups.Assets);
var tags = await tagService.GetTagsAsync(AppId, TagGroups.Assets);
return Ok(response);
Response.Headers[HeaderNames.ETag] = tags.Version.ToString();
return Ok(tags);
}
/// <summary>

22
src/Squidex/app/shared/state/languages.state.ts

@ -7,7 +7,7 @@
import { Injectable } from '@angular/core';
import { forkJoin, Observable } from 'rxjs';
import { map, tap } from 'rxjs/operators';
import { map, shareReplay, tap } from 'rxjs/operators';
import {
DialogService,
@ -65,6 +65,8 @@ type LanguageResultList = ImmutableArray<SnapshotLanguage>;
@Injectable()
export class LanguagesState extends State<Snapshot> {
private cachedLanguage$: Observable<LanguageDto[]>;
public languages =
this.project(x => x.languages);
@ -96,9 +98,7 @@ export class LanguagesState extends State<Snapshot> {
this.resetState();
}
return forkJoin(
this.languagesService.getLanguages(),
this.appLanguagesService.getLanguages(this.appName)).pipe(
return forkJoin(this.getAllLanguages(), this.getAppLanguages()).pipe(
map(args => {
return { allLanguages: args[0], languages: args[1] };
}),
@ -166,6 +166,20 @@ export class LanguagesState extends State<Snapshot> {
return this.snapshot.version;
}
private getAppLanguages() {
return this.appLanguagesService.getLanguages(this.appName);
}
private getAllLanguages() {
if (!this.cachedLanguage$) {
this.cachedLanguage$ =
this.languagesService.getLanguages().pipe(
shareReplay(1));
}
return this.cachedLanguage$;
}
private createLanguage(language: AppLanguageDto, languages: AppLanguagesList): SnapshotLanguage {
return {
language,

2
tests/Squidex.Domain.Apps.Entities.Tests/Tags/GrainTagServiceTests.cs

@ -48,7 +48,7 @@ namespace Squidex.Domain.Apps.Entities.Tags
[Fact]
public async Task Should_call_grain_when_rebuilding()
{
var tags = new TagSet();
var tags = new TagsExport();
await sut.RebuildTagsAsync(appId, TagGroups.Assets, tags);

2
tests/Squidex.Domain.Apps.Entities.Tests/Tags/TagGrainTests.cs

@ -50,7 +50,7 @@ namespace Squidex.Domain.Apps.Entities.Tags
[Fact]
public async Task Should_rebuild_tags()
{
var tags = new TagSet
var tags = new TagsExport
{
["id1"] = new Tag { Name = "name1", Count = 1 },
["id2"] = new Tag { Name = "name2", Count = 2 },

Loading…
Cancel
Save