diff --git a/backend/src/Squidex.Domain.Apps.Entities.MongoDb/Assets/MongoAssetRepository.cs b/backend/src/Squidex.Domain.Apps.Entities.MongoDb/Assets/MongoAssetRepository.cs index d4b2bc53e..5a468d8fd 100644 --- a/backend/src/Squidex.Domain.Apps.Entities.MongoDb/Assets/MongoAssetRepository.cs +++ b/backend/src/Squidex.Domain.Apps.Entities.MongoDb/Assets/MongoAssetRepository.cs @@ -6,6 +6,7 @@ // ========================================================================== using System.Runtime.CompilerServices; +using Microsoft.Extensions.Logging; using MongoDB.Driver; using Squidex.Domain.Apps.Entities.Assets; using Squidex.Domain.Apps.Entities.Assets.Repositories; @@ -21,10 +22,10 @@ public sealed partial class MongoAssetRepository : MongoRepositoryBase log) : base(database) { - countCollection = new MongoCountCollection(database, CollectionName()); + countCollection = new MongoCountCollection(database, log, CollectionName()); } public IMongoCollection GetInternalCollection() diff --git a/backend/src/Squidex.Domain.Apps.Entities.MongoDb/Contents/MongoContentCollection.cs b/backend/src/Squidex.Domain.Apps.Entities.MongoDb/Contents/MongoContentCollection.cs index d0067f2be..6904cb226 100644 --- a/backend/src/Squidex.Domain.Apps.Entities.MongoDb/Contents/MongoContentCollection.cs +++ b/backend/src/Squidex.Domain.Apps.Entities.MongoDb/Contents/MongoContentCollection.cs @@ -5,6 +5,7 @@ // All rights reserved. Licensed under the MIT license. // ========================================================================== +using Microsoft.Extensions.Logging; using MongoDB.Driver; using NodaTime; using Squidex.Domain.Apps.Core.Contents; @@ -35,7 +36,7 @@ public sealed class MongoContentCollection : MongoRepositoryBase, ICo } public MongoContentRepository(IMongoDatabase database, IAppProvider appProvider, - IOptions options) + IOptions options, ILogger log) { this.appProvider = appProvider; this.database = database; this.options = options.Value; collectionComplete = - new MongoContentCollection("States_Contents_All3", database, + new MongoContentCollection("States_Contents_All3", database, log, ReadPreference.Primary, options.Value.OptimizeForSelfHosting); collectionPublished = - new MongoContentCollection("States_Contents_Published3", database, + new MongoContentCollection("States_Contents_Published3", database, log, ReadPreference.Secondary, options.Value.OptimizeForSelfHosting); } diff --git a/backend/src/Squidex.Domain.Apps.Entities.MongoDb/MongoCountCollection.cs b/backend/src/Squidex.Domain.Apps.Entities.MongoDb/MongoCountCollection.cs index d0dc0c544..632a27b61 100644 --- a/backend/src/Squidex.Domain.Apps.Entities.MongoDb/MongoCountCollection.cs +++ b/backend/src/Squidex.Domain.Apps.Entities.MongoDb/MongoCountCollection.cs @@ -5,6 +5,7 @@ // All rights reserved. Licensed under the MIT license. // ========================================================================== +using Microsoft.Extensions.Logging; using MongoDB.Driver; using NodaTime; using Squidex.Infrastructure.MongoDb; @@ -14,17 +15,20 @@ namespace Squidex.Domain.Apps.Entities.MongoDb; internal sealed class MongoCountCollection : MongoRepositoryBase { - private readonly string name; + private readonly string collectionName; + private readonly ILogger log; - public MongoCountCollection(IMongoDatabase database, string name) + public MongoCountCollection(IMongoDatabase database, ILogger log, string name) : base(database) { - this.name = $"{name}_Count"; + this.log = log; + + collectionName = $"{name}_Count"; } protected override string CollectionName() { - return name; + return collectionName; } public async Task GetOrAddAsync(string key, Func> provider, @@ -41,30 +45,44 @@ internal sealed class MongoCountCollection : MongoRepositoryBase> provider) + { + try + { + await RefreshTotalAsync(key, cachedCount, provider, default); + } + catch (Exception ex) + { + log.LogError(ex, "Failed to update count for collection {collection}.", collectionName); + } + } + private async Task RefreshTotalAsync(string key, long cachedCount, Func> provider, CancellationToken ct) { var actualCount = await provider(ct); - if (actualCount != cachedCount) + if (actualCount == cachedCount) { - var now = SystemClock.Instance.GetCurrentInstant(); - - await Collection.UpdateOneAsync(x => x.Key == key, - Update - .Set(x => x.Key, key) - .SetOnInsert(x => x.Count, actualCount) - .SetOnInsert(x => x.Created, now), - Upsert, ct); + return actualCount; } + var now = SystemClock.Instance.GetCurrentInstant(); + + await Collection.UpdateOneAsync(x => x.Key == key, + Update + .Set(x => x.Key, key) + .SetOnInsert(x => x.Count, actualCount) + .SetOnInsert(x => x.Created, now), + Upsert, ct); + return actualCount; } diff --git a/backend/src/Squidex.Domain.Apps.Entities/Contents/ReferencesFluidExtension.cs b/backend/src/Squidex.Domain.Apps.Entities/Contents/ReferencesFluidExtension.cs index 89f1d43a4..a18f5b458 100644 --- a/backend/src/Squidex.Domain.Apps.Entities/Contents/ReferencesFluidExtension.cs +++ b/backend/src/Squidex.Domain.Apps.Entities/Contents/ReferencesFluidExtension.cs @@ -12,7 +12,6 @@ using Fluid.Values; using Microsoft.Extensions.DependencyInjection; using Squidex.Domain.Apps.Core.Rules.EnrichedEvents; using Squidex.Domain.Apps.Core.Templates; -using Squidex.Domain.Apps.Entities.Contents.Queries.Steps; using Squidex.Infrastructure; using static Parlot.Fluent.Parsers; diff --git a/backend/tests/Squidex.Domain.Apps.Entities.Tests/Assets/MongoDb/AssetsQueryFixture.cs b/backend/tests/Squidex.Domain.Apps.Entities.Tests/Assets/MongoDb/AssetsQueryFixture.cs index 73ed4e17c..fe691d551 100644 --- a/backend/tests/Squidex.Domain.Apps.Entities.Tests/Assets/MongoDb/AssetsQueryFixture.cs +++ b/backend/tests/Squidex.Domain.Apps.Entities.Tests/Assets/MongoDb/AssetsQueryFixture.cs @@ -6,6 +6,7 @@ // ========================================================================== using System.Globalization; +using Microsoft.Extensions.Logging; using MongoDB.Bson; using MongoDB.Driver; using NodaTime; @@ -42,7 +43,7 @@ public sealed class AssetsQueryFixture : IAsyncLifetime mongoClient = new MongoClient(TestConfig.Configuration["mongodb:configuration"]); mongoDatabase = mongoClient.GetDatabase(TestConfig.Configuration["mongodb:database"]); - AssetRepository = new MongoAssetRepository(mongoDatabase); + AssetRepository = new MongoAssetRepository(mongoDatabase, A.Fake>()); } public Task DisposeAsync() diff --git a/backend/tests/Squidex.Domain.Apps.Entities.Tests/Contents/MongoDb/ContentsQueryFixture.cs b/backend/tests/Squidex.Domain.Apps.Entities.Tests/Contents/MongoDb/ContentsQueryFixture.cs index 8e536f692..f68a89b5e 100644 --- a/backend/tests/Squidex.Domain.Apps.Entities.Tests/Contents/MongoDb/ContentsQueryFixture.cs +++ b/backend/tests/Squidex.Domain.Apps.Entities.Tests/Contents/MongoDb/ContentsQueryFixture.cs @@ -7,6 +7,7 @@ using System.Globalization; using LoremNET; +using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; using MongoDB.Bson; using MongoDB.Driver; @@ -82,11 +83,7 @@ public abstract class ContentsQueryFixtureBase : IAsyncLifetime OptimizeForSelfHosting = dedicatedCollections }); - ContentRepository = - new MongoContentRepository( - mongoDatabase, - appProvider, - options); + ContentRepository = new MongoContentRepository(mongoDatabase, appProvider, options, A.Fake>()); } public Task DisposeAsync()