Skip to content

Commit 5b2472c

Browse files
authored
0.5.6 update and improving file based storage resiliency (#185)
- References are only saved on set, not on flush. Required to avoid excessive serialisation or IO - Added logging capability - FileStorage now writes to a temp file and moves to original location (framework dependent how). Should provide better resiliency in case app crashes - Set version to 0.5.6
1 parent 119d47a commit 5b2472c

File tree

22 files changed

+924
-622
lines changed

22 files changed

+924
-622
lines changed

src/CsharpClient/QuixStreams.RawReadSamples/QuixStreams.RawReadSamples.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
<PropertyGroup>
44
<OutputType>Exe</OutputType>
5-
<TargetFramework>net6.0</TargetFramework>
5+
<TargetFramework>net8.0</TargetFramework>
66
<Configurations>Debug;Release;Python</Configurations>
77
<Platforms>AnyCPU</Platforms>
88
</PropertyGroup>

src/CsharpClient/QuixStreams.State.UnitTests/BaseCrudShould.cs

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,19 @@
44
using QuixStreams.State.Storage;
55
using QuixStreams.State.Storage.FileStorage;
66
using Xunit;
7+
using Xunit.Abstractions;
78

89
namespace QuixStreams.State.UnitTests
910
{
1011
public abstract class BaseCRUDShould
1112
{
13+
protected readonly ITestOutputHelper output;
14+
15+
public BaseCRUDShould(ITestOutputHelper output)
16+
{
17+
this.output = output;
18+
}
19+
1220
protected abstract BaseFileStorage GetStorage();
1321

1422
protected async Task testLong(BaseFileStorage storage, string key, long inp)
@@ -190,5 +198,36 @@ public async Task TestClearStorage()
190198
(await storage.GetAllKeysAsync()).Length.Should().Be(0);
191199
}
192200

201+
[Theory(Skip = "Intended for local use only")]
202+
[InlineData(100, 512)]
203+
[InlineData(1000, 512)]
204+
205+
[InlineData(100, 1024*1024)]
206+
[InlineData(1000, 1024*1024)]
207+
208+
[InlineData(10, 1024*1024*1024)]
209+
[InlineData(100, 1024*1024*1024)]
210+
public async Task PerfTest(int count, int size)
211+
{
212+
var start = DateTime.UtcNow;
213+
214+
var storage = this.GetStorage();
215+
216+
var bytes = new byte[size];
217+
var random = new Random();
218+
219+
for (int i = 0; i < count; i++)
220+
{
221+
random.NextBytes(bytes);
222+
await storage.SaveRaw($"KEY_{i}", bytes);
223+
await storage.SaveRaw($"KEY_{i}", bytes);
224+
}
225+
226+
227+
var end = DateTime.UtcNow;
228+
this.output.WriteLine($"Took {end-start:g}");
229+
230+
}
231+
193232
}
194233
}

src/CsharpClient/QuixStreams.State.UnitTests/LocalCrudShould.cs

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,20 @@
1+
using Quix.TestBase.Extensions;
12
using QuixStreams.State.Storage;
23
using QuixStreams.State.Storage.FileStorage;
34
using QuixStreams.State.Storage.FileStorage.LocalFileStorage;
5+
using Xunit.Abstractions;
46

57
namespace QuixStreams.State.UnitTests
68
{
79
public class LocalCRUDShould : BaseCRUDShould
810
{
9-
override
10-
protected BaseFileStorage GetStorage()
11+
public LocalCRUDShould(ITestOutputHelper output) : base(output)
1112
{
12-
var storage = new LocalFileStorage();
13+
}
14+
15+
protected override BaseFileStorage GetStorage()
16+
{
17+
var storage = new LocalFileStorage(loggerFactory:this.output.CreateLoggerFactory());
1318
storage.Clear();
1419
return storage;
1520
}

src/CsharpClient/QuixStreams.State.UnitTests/ScalarStateShould.cs

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using System;
2+
using System.Collections.Generic;
23
using FluentAssertions;
34
using QuixStreams.State.Storage;
45
using Xunit;
@@ -64,6 +65,36 @@ public void Flush_Value_ShouldPersistChangesToStorage()
6465
storage.Get(ScalarState.StorageKey).StringValue.Should().BeEquivalentTo("value");
6566
}
6667

68+
[Fact]
69+
public void ListConversion_ShouldStoreAndRetrieveCorrectly()
70+
{
71+
var storage = new InMemoryStorage();
72+
var key = "TestKey";
73+
var state = new DictionaryState<List<int>>(storage);
74+
state.Clear();
75+
76+
var list = new List<int>();
77+
state[key] = list;
78+
state[key].Add(1);
79+
list.Add(2);
80+
list.Add(3);
81+
82+
// No change is expected!
83+
state[key].Should().BeEquivalentTo(new List<StateTemplatedShould.CustomClass>());
84+
85+
state[key] = list;
86+
87+
state[key].Count.Should().Be(2);
88+
state[key].Should().BeEquivalentTo(list, o => o.WithStrictOrdering());
89+
90+
state.Flush();
91+
92+
var state2 = new DictionaryState<List<int>>(storage);
93+
94+
state2[key].Count.Should().Be(2);
95+
state2[key].Should().BeEquivalentTo(list, o => o.WithStrictOrdering());
96+
}
97+
6798
[Fact]
6899
public void Flush_ClearBeforeFlush_ShouldClearStorage()
69100
{

0 commit comments

Comments
 (0)