From 329ae5dd2f8bab9db99d29c7dccea58608b808f0 Mon Sep 17 00:00:00 2001 From: Sebastian Stehle Date: Thu, 14 Mar 2024 08:28:49 +0100 Subject: [PATCH] Fix double sharding. --- .../Assets/MongoShardedAssetRepository.cs | 7 +----- .../Contents/MongoShardedContentRepository.cs | 7 +----- .../ShardedSnapshotStore.cs | 19 +++++++-------- .../Text/MongoShardedTextIndex.cs | 14 ++++------- .../States/ShardedService.cs | 24 +++++++------------ .../States/ShardedServiceTests.cs | 4 ++-- 6 files changed, 26 insertions(+), 49 deletions(-) diff --git a/backend/src/Squidex.Domain.Apps.Entities.MongoDb/Assets/MongoShardedAssetRepository.cs b/backend/src/Squidex.Domain.Apps.Entities.MongoDb/Assets/MongoShardedAssetRepository.cs index d6652dca3..f3a728309 100644 --- a/backend/src/Squidex.Domain.Apps.Entities.MongoDb/Assets/MongoShardedAssetRepository.cs +++ b/backend/src/Squidex.Domain.Apps.Entities.MongoDb/Assets/MongoShardedAssetRepository.cs @@ -16,7 +16,7 @@ namespace Squidex.Domain.Apps.Entities.MongoDb.Assets; public sealed class MongoShardedAssetRepository : ShardedSnapshotStore, IAssetRepository, IDeleter { public MongoShardedAssetRepository(IShardingStrategy sharding, Func factory) - : base(sharding, factory) + : base(sharding, factory, x => x.AppId.Id) { } @@ -82,9 +82,4 @@ public sealed class MongoShardedAssetRepository : ShardedSnapshotStore, IContentRepository, IDeleter { public MongoShardedContentRepository(IShardingStrategy sharding, Func factory) - : base(sharding, factory) + : base(sharding, factory, x => x.AppId.Id) { } @@ -90,9 +90,4 @@ public sealed class MongoShardedContentRepository : ShardedSnapshotStore : ShardedService, ISnapshotStore, IDeleter where T : ISnapshotStore, IDeleter +public abstract class ShardedSnapshotStore : ShardedService, ISnapshotStore, IDeleter where TStore : ISnapshotStore, IDeleter { - protected ShardedSnapshotStore(IShardingStrategy sharding, Func factory) + private readonly Func getShardKey; + + protected ShardedSnapshotStore(IShardingStrategy sharding, Func factory, Func getShardKey) : base(sharding, factory) { + this.getShardKey = getShardKey; } - protected abstract string GetShardKey(TState state); - public Task WriteAsync(SnapshotWriteJob job, CancellationToken ct = default) { - var shard = Shard(GetShardKey(job.Value)); + var shard = Shard(getShardKey(job.Value)); return shard.WriteAsync(job, ct); } @@ -77,12 +78,10 @@ public abstract class ShardedSnapshotStore : ShardedService, ISnap public async Task WriteManyAsync(IEnumerable> jobs, CancellationToken ct = default) { - // Some commands might share a shared, therefore we don't group by app id. - foreach (var byShard in jobs.GroupBy(c => GetShardKey(c.Value))) + // Reduce the number of writes by grouping by shard. + foreach (var byShard in jobs.GroupBy(c => Shard(getShardKey(c.Value)))) { - var shard = Shard(byShard.Key); - - await shard.WriteManyAsync(byShard.ToArray(), ct); + await byShard.Key.WriteManyAsync(byShard.ToArray(), ct); } } diff --git a/backend/src/Squidex.Domain.Apps.Entities.MongoDb/Text/MongoShardedTextIndex.cs b/backend/src/Squidex.Domain.Apps.Entities.MongoDb/Text/MongoShardedTextIndex.cs index 2ee73e1cc..0dd69bb32 100644 --- a/backend/src/Squidex.Domain.Apps.Entities.MongoDb/Text/MongoShardedTextIndex.cs +++ b/backend/src/Squidex.Domain.Apps.Entities.MongoDb/Text/MongoShardedTextIndex.cs @@ -13,7 +13,7 @@ using Squidex.Infrastructure.States; namespace Squidex.Domain.Apps.Entities.MongoDb.Text; -public sealed class MongoShardedTextIndex : ShardedService>, ITextIndex, IDeleter where T : class +public sealed class MongoShardedTextIndex : ShardedService>, ITextIndex, IDeleter where T : class { public MongoShardedTextIndex(IShardingStrategy sharding, Func> factory) : base(sharding, factory) @@ -32,12 +32,10 @@ public sealed class MongoShardedTextIndex : ShardedService GetShardKey(c.UniqueContentId.AppId))) + // Reduce the number of writes by grouping by shard. + foreach (var byShard in commands.GroupBy(c => Shard(c.UniqueContentId.AppId))) { - var shard = Shard(byShard.Key); - - await shard.ExecuteAsync(byShard.ToArray(), ct); + await byShard.Key.ExecuteAsync(byShard.ToArray(), ct); } } @@ -56,9 +54,7 @@ public sealed class MongoShardedTextIndex : ShardedService : IInitializable +public abstract class ShardedService : IInitializable where TKey : notnull { - private readonly Dictionary shards = new Dictionary(); + private readonly Dictionary shards = []; private readonly IShardingStrategy sharding; - private readonly Func factory; + private readonly Func factory; - protected IEnumerable Shards => shards.Values; + protected IEnumerable Shards => shards.Values; - protected ShardedService(IShardingStrategy sharding, Func factory) + protected ShardedService(IShardingStrategy sharding, Func factory) { this.sharding = sharding; this.factory = factory; @@ -51,18 +51,10 @@ public abstract class ShardedService : IInitializable } } - protected string GetShardKey(TKey key) where TKey : notnull + protected TService Shard(TKey key) { - return sharding.GetShardKey(key); - } + var shardKey = sharding.GetShardKey(key); - protected T Shard(TKey key) where TKey : notnull - { - return shards[GetShardKey(key)]; - } - - protected string GetShardKey(DomainId appId) - { - return sharding.GetShardKey(appId); + return shards[shardKey]; } } diff --git a/backend/tests/Squidex.Infrastructure.Tests/States/ShardedServiceTests.cs b/backend/tests/Squidex.Infrastructure.Tests/States/ShardedServiceTests.cs index c265e24aa..b6fa895f8 100644 --- a/backend/tests/Squidex.Infrastructure.Tests/States/ShardedServiceTests.cs +++ b/backend/tests/Squidex.Infrastructure.Tests/States/ShardedServiceTests.cs @@ -19,14 +19,14 @@ public class ShardedServiceTests { } - private class TestSut : ShardedService + private class TestSut : ShardedService { public TestSut(IShardingStrategy sharding, Func factory) : base(sharding, factory) { } - public IInner ExposeShard(TKey key) where TKey : notnull + public IInner ExposeShard(int key) { return Shard(key); }