From cc2784a269a0a1f27cb0472403fa9e81669a8524 Mon Sep 17 00:00:00 2001 From: fluxzy-ci Date: Sat, 11 Apr 2026 18:44:59 +0200 Subject: [PATCH] Fix concurrent HashSet modification when serializing archive meta UpdateMeta, UpdateTags and Update(ExchangeInfo) all touched _archiveMetaInformation.Tags but guarded it with two different locks (one on the path string, another on the meta object itself), so a thread adding a tag could race a thread serializing the meta file and trip "Collection was modified" inside JsonSerializer. Route every access through a single _metaLock and keep UpdateMeta inside the lock. --- .../Writers/DirectoryArchiveWriter.cs | 21 ++++++++++--------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/src/Fluxzy.Core/Archiving/Writers/DirectoryArchiveWriter.cs b/src/Fluxzy.Core/Archiving/Writers/DirectoryArchiveWriter.cs index 435565f4..9640693a 100644 --- a/src/Fluxzy.Core/Archiving/Writers/DirectoryArchiveWriter.cs +++ b/src/Fluxzy.Core/Archiving/Writers/DirectoryArchiveWriter.cs @@ -17,6 +17,7 @@ namespace Fluxzy.Writers public class DirectoryArchiveWriter : RealtimeArchiveWriter { private readonly ArchiveMetaInformation _archiveMetaInformation = CreateNewCaptureArchiveMetaInformation(); + private readonly object _metaLock = new object(); private static ArchiveMetaInformation CreateNewCaptureArchiveMetaInformation() { @@ -78,7 +79,7 @@ private void UpdateMeta(bool force) if (!force && File.Exists(_archiveMetaInformationPath)) return; - lock (_archiveMetaInformationPath) + lock (_metaLock) { using var fileStream = File.Create(_archiveMetaInformationPath); JsonSerializer.Serialize(fileStream, _archiveMetaInformation, GlobalArchiveOption.DefaultSerializerOptions); @@ -87,15 +88,15 @@ private void UpdateMeta(bool force) public override void UpdateTags(IEnumerable tags) { - lock (_archiveMetaInformationPath) + lock (_metaLock) { foreach (var tag in tags) { _archiveMetaInformation.Tags.Add(tag); } - } - UpdateMeta(true); + UpdateMeta(true); + } } protected override bool ExchangeUpdateRequired(Exchange exchange) @@ -130,18 +131,18 @@ public override bool Update(ExchangeInfo exchangeInfo, CancellationToken cancell if (exchangeInfo.Tags?.Any() ?? false) { - var modified = false; - - lock (_archiveMetaInformation) { + lock (_metaLock) + { + var modified = false; foreach (var tag in exchangeInfo.Tags) { modified = _archiveMetaInformation.Tags.Add(tag) || modified; } - } - if (modified) - UpdateMeta(true); + if (modified) + UpdateMeta(true); + } } return true;