Browse Source

Do not cancel count query. (#956)

pull/959/head
Sebastian Stehle 4 years ago
committed by GitHub
parent
commit
51d95c368c
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 5
      backend/src/Squidex.Domain.Apps.Entities.MongoDb/Assets/MongoAssetRepository.cs
  2. 5
      backend/src/Squidex.Domain.Apps.Entities.MongoDb/Contents/MongoContentCollection.cs
  3. 7
      backend/src/Squidex.Domain.Apps.Entities.MongoDb/Contents/MongoContentRepository.cs
  4. 48
      backend/src/Squidex.Domain.Apps.Entities.MongoDb/MongoCountCollection.cs
  5. 1
      backend/src/Squidex.Domain.Apps.Entities/Contents/ReferencesFluidExtension.cs
  6. 3
      backend/tests/Squidex.Domain.Apps.Entities.Tests/Assets/MongoDb/AssetsQueryFixture.cs
  7. 7
      backend/tests/Squidex.Domain.Apps.Entities.Tests/Contents/MongoDb/ContentsQueryFixture.cs

5
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<MongoAsse
{
private readonly MongoCountCollection countCollection;
public MongoAssetRepository(IMongoDatabase database)
public MongoAssetRepository(IMongoDatabase database, ILogger<MongoAssetRepository> log)
: base(database)
{
countCollection = new MongoCountCollection(database, CollectionName());
countCollection = new MongoCountCollection(database, log, CollectionName());
}
public IMongoCollection<MongoAssetEntity> GetInternalCollection()

5
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<MongoContentEnt
private readonly ReadPreference readPreference;
private readonly string name;
public MongoContentCollection(string name, IMongoDatabase database, ReadPreference readPreference,
public MongoContentCollection(string name, IMongoDatabase database, ILogger log, ReadPreference readPreference,
bool dedicatedCollections)
: base(database)
{
@ -47,7 +48,7 @@ public sealed class MongoContentCollection : MongoRepositoryBase<MongoContentEnt
queryReferences = new QueryReferences(queryByIds);
queryReferrers = new QueryReferrers();
queryScheduled = new QueryScheduled();
queryByQuery = new QueryByQuery(new MongoCountCollection(database, name));
queryByQuery = new QueryByQuery(new MongoCountCollection(database, log, name));
if (dedicatedCollections)
{

7
backend/src/Squidex.Domain.Apps.Entities.MongoDb/Contents/MongoContentRepository.cs

@ -5,6 +5,7 @@
// All rights reserved. Licensed under the MIT license.
// ==========================================================================
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using MongoDB.Driver;
using MongoDB.Driver.Core.Clusters;
@ -41,18 +42,18 @@ public partial class MongoContentRepository : MongoBase<MongoContentEntity>, ICo
}
public MongoContentRepository(IMongoDatabase database, IAppProvider appProvider,
IOptions<ContentOptions> options)
IOptions<ContentOptions> options, ILogger<MongoContentRepository> 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);
}

48
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<MongoCountEntity>
{
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<long> GetOrAddAsync(string key, Func<CancellationToken, Task<long>> provider,
@ -41,30 +45,44 @@ internal sealed class MongoCountCollection : MongoRepositoryBase<MongoCountEntit
if (isOutdated)
{
// If we have a loot of items, the query might be slow and therefore we execute it in the background.
RefreshTotalAsync(key, cachedTotal, provider, ct).Forget();
// If we have a lot of items, the query might be slow and therefore we execute it in the background.
RefreshSilentAsync(key, cachedTotal, provider).Forget();
}
return cachedTotal;
}
private async Task RefreshSilentAsync(string key, long cachedCount, Func<CancellationToken, Task<long>> 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<long> RefreshTotalAsync(string key, long cachedCount, Func<CancellationToken, Task<long>> 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;
}

1
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;

3
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<ILogger<MongoAssetRepository>>());
}
public Task DisposeAsync()

7
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<ILogger<MongoContentRepository>>());
}
public Task DisposeAsync()

Loading…
Cancel
Save