Add comments for ScenarioStateStore related code (#1433)

This commit is contained in:
Stef Heyenrath
2026-03-30 19:49:28 +02:00
committed by GitHub
parent b4f5b9256c
commit 6c6a42979e
5 changed files with 42 additions and 15 deletions

View File

@@ -1,7 +1,5 @@
// Copyright © WireMock.Net // Copyright © WireMock.Net
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis; using System.Diagnostics.CodeAnalysis;
namespace WireMock.Handlers; namespace WireMock.Handlers;

View File

@@ -1,43 +1,53 @@
// Copyright © WireMock.Net // Copyright © WireMock.Net
using System;
using System.Collections.Concurrent; using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis; using System.Diagnostics.CodeAnalysis;
using System.IO;
using System.Linq;
using Newtonsoft.Json; using Newtonsoft.Json;
using Stef.Validation;
namespace WireMock.Handlers; namespace WireMock.Handlers;
/// <summary>
/// Provides a file-based implementation of <see cref="IScenarioStateStore" /> that persists scenario states to disk and allows concurrent access.
/// </summary>
public class FileBasedScenarioStateStore : IScenarioStateStore public class FileBasedScenarioStateStore : IScenarioStateStore
{ {
private readonly ConcurrentDictionary<string, ScenarioState> _scenarios = new(StringComparer.OrdinalIgnoreCase); private readonly ConcurrentDictionary<string, ScenarioState> _scenarios = new(StringComparer.OrdinalIgnoreCase);
private readonly string _scenariosFolder; private readonly string _scenariosFolder;
private readonly object _lock = new(); private readonly object _lock = new();
/// <summary>
/// Initializes a new instance of the FileBasedScenarioStateStore class using the specified root folder as the base directory for scenario state storage.
/// </summary>
/// <param name="rootFolder">The root directory under which scenario state data will be stored. Must be a valid file system path.</param>
public FileBasedScenarioStateStore(string rootFolder) public FileBasedScenarioStateStore(string rootFolder)
{ {
Guard.NotNullOrEmpty(rootFolder);
_scenariosFolder = Path.Combine(rootFolder, "__admin", "scenarios"); _scenariosFolder = Path.Combine(rootFolder, "__admin", "scenarios");
Directory.CreateDirectory(_scenariosFolder); Directory.CreateDirectory(_scenariosFolder);
LoadScenariosFromDisk(); LoadScenariosFromDisk();
} }
/// <inheritdoc />
public bool TryGet(string name, [NotNullWhen(true)] out ScenarioState? state) public bool TryGet(string name, [NotNullWhen(true)] out ScenarioState? state)
{ {
return _scenarios.TryGetValue(name, out state); return _scenarios.TryGetValue(name, out state);
} }
/// <inheritdoc />
public IReadOnlyList<ScenarioState> GetAll() public IReadOnlyList<ScenarioState> GetAll()
{ {
return _scenarios.Values.ToArray(); return _scenarios.Values.ToArray();
} }
/// <inheritdoc />
public bool ContainsKey(string name) public bool ContainsKey(string name)
{ {
return _scenarios.ContainsKey(name); return _scenarios.ContainsKey(name);
} }
/// <inheritdoc />
public bool TryAdd(string name, ScenarioState scenarioState) public bool TryAdd(string name, ScenarioState scenarioState)
{ {
if (_scenarios.TryAdd(name, scenarioState)) if (_scenarios.TryAdd(name, scenarioState))
@@ -49,6 +59,7 @@ public class FileBasedScenarioStateStore : IScenarioStateStore
return false; return false;
} }
/// <inheritdoc />
public ScenarioState AddOrUpdate(string name, Func<string, ScenarioState> addFactory, Func<string, ScenarioState, ScenarioState> updateFactory) public ScenarioState AddOrUpdate(string name, Func<string, ScenarioState> addFactory, Func<string, ScenarioState, ScenarioState> updateFactory)
{ {
lock (_lock) lock (_lock)
@@ -59,6 +70,7 @@ public class FileBasedScenarioStateStore : IScenarioStateStore
} }
} }
/// <inheritdoc />
public ScenarioState? Update(string name, Action<ScenarioState> updateAction) public ScenarioState? Update(string name, Action<ScenarioState> updateAction)
{ {
lock (_lock) lock (_lock)
@@ -74,6 +86,7 @@ public class FileBasedScenarioStateStore : IScenarioStateStore
} }
} }
/// <inheritdoc />
public bool TryRemove(string name) public bool TryRemove(string name)
{ {
if (_scenarios.TryRemove(name, out _)) if (_scenarios.TryRemove(name, out _))
@@ -85,6 +98,7 @@ public class FileBasedScenarioStateStore : IScenarioStateStore
return false; return false;
} }
/// <inheritdoc />
public void Clear() public void Clear()
{ {
_scenarios.Clear(); _scenarios.Clear();

View File

@@ -1,42 +1,48 @@
// Copyright © WireMock.Net // Copyright © WireMock.Net
using System;
using System.Collections.Concurrent; using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis; using System.Diagnostics.CodeAnalysis;
using System.Linq;
namespace WireMock.Handlers; namespace WireMock.Handlers;
/// <summary>
/// Provides an in-memory implementation of the <see cref="IScenarioStateStore" /> interface for managing scenario state objects by name.
/// </summary>
public class InMemoryScenarioStateStore : IScenarioStateStore public class InMemoryScenarioStateStore : IScenarioStateStore
{ {
private readonly ConcurrentDictionary<string, ScenarioState> _scenarios = new(StringComparer.OrdinalIgnoreCase); private readonly ConcurrentDictionary<string, ScenarioState> _scenarios = new(StringComparer.OrdinalIgnoreCase);
/// <inheritdoc />
public bool TryGet(string name, [NotNullWhen(true)] out ScenarioState? state) public bool TryGet(string name, [NotNullWhen(true)] out ScenarioState? state)
{ {
return _scenarios.TryGetValue(name, out state); return _scenarios.TryGetValue(name, out state);
} }
/// <inheritdoc />
public IReadOnlyList<ScenarioState> GetAll() public IReadOnlyList<ScenarioState> GetAll()
{ {
return _scenarios.Values.ToArray(); return _scenarios.Values.ToArray();
} }
/// <inheritdoc />
public bool ContainsKey(string name) public bool ContainsKey(string name)
{ {
return _scenarios.ContainsKey(name); return _scenarios.ContainsKey(name);
} }
/// <inheritdoc />
public bool TryAdd(string name, ScenarioState scenarioState) public bool TryAdd(string name, ScenarioState scenarioState)
{ {
return _scenarios.TryAdd(name, scenarioState); return _scenarios.TryAdd(name, scenarioState);
} }
/// <inheritdoc />
public ScenarioState AddOrUpdate(string name, Func<string, ScenarioState> addFactory, Func<string, ScenarioState, ScenarioState> updateFactory) public ScenarioState AddOrUpdate(string name, Func<string, ScenarioState> addFactory, Func<string, ScenarioState, ScenarioState> updateFactory)
{ {
return _scenarios.AddOrUpdate(name, addFactory, updateFactory); return _scenarios.AddOrUpdate(name, addFactory, updateFactory);
} }
/// <inheritdoc />
public ScenarioState? Update(string name, Action<ScenarioState> updateAction) public ScenarioState? Update(string name, Action<ScenarioState> updateAction)
{ {
if (_scenarios.TryGetValue(name, out var state)) if (_scenarios.TryGetValue(name, out var state))
@@ -48,11 +54,13 @@ public class InMemoryScenarioStateStore : IScenarioStateStore
return null; return null;
} }
/// <inheritdoc />
public bool TryRemove(string name) public bool TryRemove(string name)
{ {
return _scenarios.TryRemove(name, out _); return _scenarios.TryRemove(name, out _);
} }
/// <inheritdoc />
public void Clear() public void Clear()
{ {
_scenarios.Clear(); _scenarios.Clear();

View File

@@ -175,6 +175,13 @@ public class WireMockServerSettings
[JsonIgnore] [JsonIgnore]
public IFileSystemHandler FileSystemHandler { get; set; } = null!; public IFileSystemHandler FileSystemHandler { get; set; } = null!;
/// <summary>
/// Gets or sets the store used to persist scenario state information.
/// </summary>
/// <remarks>
/// The scenario state store manages the storage and retrieval of state data associated with scenarios.
/// By default, an in-memory implementation is used, but this property can be set to a custom implementation to support alternative storage mechanisms such as databases or distributed caches.
/// </remarks>
[PublicAPI] [PublicAPI]
[JsonIgnore] [JsonIgnore]
public IScenarioStateStore ScenarioStateStore { get; set; } = new InMemoryScenarioStateStore(); public IScenarioStateStore ScenarioStateStore { get; set; } = new InMemoryScenarioStateStore();

View File

@@ -11,12 +11,12 @@
<ItemGroup> <ItemGroup>
<PackageReference Include="AwesomeAssertions" Version="9.4.0" /> <PackageReference Include="AwesomeAssertions" Version="9.4.0" />
<PackageReference Include="coverlet.collector" Version="6.0.4"> <PackageReference Include="coverlet.collector" Version="8.0.1">
<PrivateAssets>all</PrivateAssets> <PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference> </PackageReference>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="18.3.0" /> <PackageReference Include="Microsoft.NET.Test.Sdk" Version="18.3.0" />
<PackageReference Include="WireMock.Net" Version="1.25.0" /> <PackageReference Include="WireMock.Net" Version="2.1.0" />
<PackageReference Include="xunit.v3" Version="3.2.2" /> <PackageReference Include="xunit.v3" Version="3.2.2" />
<PackageReference Include="xunit.runner.visualstudio" Version="3.1.5"> <PackageReference Include="xunit.runner.visualstudio" Version="3.1.5">
<PrivateAssets>all</PrivateAssets> <PrivateAssets>all</PrivateAssets>