From 5783bf967e6d188163cf678780326fad4d5c1093 Mon Sep 17 00:00:00 2001 From: stidsborg Date: Fri, 20 Dec 2024 14:43:45 +0100 Subject: [PATCH] Inlined IsState boolean in EffectId --- .../InMemoryTests/DelimiterTests.cs | 11 +-- .../TestTemplates/EffectStoreTests.cs | 61 +++++++---------- .../RFunctionTests/ControlPanelTests.cs | 12 ++-- .../RFunctionTests/CrashedTests.cs | 4 +- .../RFunctionTests/EffectImplicitIdTests.cs | 28 ++++---- .../RFunctionTests/EffectTests.cs | 24 +++---- .../RFunctionTests/PostponedTests.cs | 4 +- .../ScheduleReInvocationTests.cs | 4 +- .../RFunctionTests/SunshineTests.cs | 2 +- .../ResilientFunctionStateTests.cs | 3 +- .../TestTemplates/StatesStoreTests.cs | 9 ++- .../TestTemplates/StoreCrudTests.cs | 2 +- .../TestTemplates/StoreTests.cs | 4 +- .../WatchDogsTests/WatchdogCompoundTests.cs | 4 +- .../Domain/Effect.cs | 67 ++++++++++--------- .../Domain/EffectId.cs | 24 ++----- .../Domain/ExistingEffects.cs | 18 ++--- .../Domain/ExistingStates.cs | 4 +- .../Domain/StateFetcher.cs | 2 +- .../Domain/States.cs | 4 +- .../Storage/InMemoryEffectsStore.cs | 2 +- .../Storage/Types.cs | 13 ++-- .../MariaDbEffectsStore.cs | 7 +- .../PostgreSqlEffectsStore.cs | 6 +- .../SqlServerEffectsStore.cs | 6 +- 25 files changed, 145 insertions(+), 180 deletions(-) diff --git a/Core/Cleipnir.ResilientFunctions.Tests/InMemoryTests/DelimiterTests.cs b/Core/Cleipnir.ResilientFunctions.Tests/InMemoryTests/DelimiterTests.cs index 48d36da4..6c530320 100644 --- a/Core/Cleipnir.ResilientFunctions.Tests/InMemoryTests/DelimiterTests.cs +++ b/Core/Cleipnir.ResilientFunctions.Tests/InMemoryTests/DelimiterTests.cs @@ -8,23 +8,16 @@ namespace Cleipnir.ResilientFunctions.Tests.InMemoryTests; public class DelimiterTests { [TestMethod] - public void flowInstanceMustNotContainUnitDelimiter() + public void FlowInstanceMustNotContainUnitDelimiter() { var invalidId = "Test" + Delimiters.UnitSeparator; Assert.ThrowsException(() => new FlowInstance(invalidId)); } [TestMethod] - public void flowTypeMustNotContainUnitDelimiter() + public void FlowTypeMustNotContainUnitDelimiter() { var invalidId = "Test" + Delimiters.UnitSeparator; Assert.ThrowsException(() => new FlowType(invalidId)); } - - [TestMethod] - public void EffectIdIdMustNotContainUnitDelimiter() - { - var invalidId = "Test" + Delimiters.UnitSeparator; - Assert.ThrowsException(() => new EffectId(invalidId)); - } } \ No newline at end of file diff --git a/Core/Cleipnir.ResilientFunctions.Tests/TestTemplates/EffectStoreTests.cs b/Core/Cleipnir.ResilientFunctions.Tests/TestTemplates/EffectStoreTests.cs index afc7e929..6fddca04 100644 --- a/Core/Cleipnir.ResilientFunctions.Tests/TestTemplates/EffectStoreTests.cs +++ b/Core/Cleipnir.ResilientFunctions.Tests/TestTemplates/EffectStoreTests.cs @@ -16,17 +16,15 @@ protected async Task SunshineScenarioTest(Task storeTask) var store = await storeTask; var functionId = TestStoredId.Create(); var storedEffect1 = new StoredEffect( - "EffectId1", - "EffectId1".ToStoredEffectId(), - IsState: false, + "EffectId1".ToEffectId(), + "EffectId1".ToStoredEffectId(isState: false), WorkStatus.Started, Result: null, StoredException: null ); var storedEffect2 = new StoredEffect( - "EffectId2", - "EffectId2".ToStoredEffectId(), - IsState: false, + "EffectId2".ToEffectId(), + "EffectId2".ToStoredEffectId(isState: false), WorkStatus.Completed, Result: null, StoredException: null @@ -66,9 +64,8 @@ protected async Task SingleEffectWithResultLifeCycle(Task storeTa var store = await storeTask; var functionId = TestStoredId.Create(); var effect = new StoredEffect( - "EffectId1", - "EffectId1".ToStoredEffectId(), - IsState: false, + "EffectId1".ToEffectId(), + "EffectId1".ToStoredEffectId(isState: false), WorkStatus.Started, Result: null, StoredException: null @@ -90,7 +87,6 @@ await store.GetEffectResults(functionId) storedEffect.StoredException.ShouldBe(effect.StoredException); storedEffect.Result!.ToStringFromUtf8Bytes().ShouldBe(effect.Result.ToStringFromUtf8Bytes()); storedEffect.WorkStatus.ShouldBe(effect.WorkStatus); - storedEffect.IsState.ShouldBe(effect.IsState); } @@ -105,9 +101,8 @@ protected async Task SingleFailingEffectLifeCycle(Task storeTask) "Some Exception Type" ); var storedEffect = new StoredEffect( - "EffectId1", - "EffectId1".ToStoredEffectId(), - IsState: false, + "EffectId1".ToEffectId(), + "EffectId1".ToStoredEffectId(isState: false), WorkStatus.Started, Result: null, StoredException: null @@ -133,17 +128,15 @@ protected async Task EffectCanBeDeleted(Task storeTask) var store = await storeTask; var functionId = TestStoredId.Create(); var storedEffect1 = new StoredEffect( - "EffectId1", - "EffectId1".ToStoredEffectId(), - IsState: false, + "EffectId1".ToEffectId(), + "EffectId1".ToStoredEffectId(isState: false), WorkStatus.Started, Result: null, StoredException: null ); var storedEffect2 = new StoredEffect( - "EffectId2", - "EffectId2".ToStoredEffectId(), - IsState: false, + "EffectId2".ToEffectId(), + "EffectId2".ToStoredEffectId(isState: false), WorkStatus.Completed, Result: null, StoredException: null @@ -181,17 +174,15 @@ protected async Task DeleteFunctionIdDeletesAllRelatedEffects(Task storeTask) var otherFunctionId = new StoredId(functionId.Type, Instance: (functionId.Instance + "123").ToStoredInstance()); var storedEffect1 = new StoredEffect( - "EffectId1", - "EffectId1".ToStoredEffectId(), - IsState: false, + "EffectId1".ToEffectId(), + "EffectId1".ToStoredEffectId(isState: false), WorkStatus.Started, Result: null, StoredException: null ); var storedEffect2 = new StoredEffect( - "EffectId2", - "EffectId2".ToStoredEffectId(), - IsState: false, + "EffectId2".ToEffectId(), + "EffectId2".ToStoredEffectId(isState: false), WorkStatus.Completed, Result: null, StoredException: null @@ -266,17 +255,15 @@ protected async Task BulkInsertTest(Task storeTask) var store = await storeTask; var storedId = TestStoredId.Create(); var storedEffect1 = new StoredEffect( - "EffectId1", - "EffectId1".ToStoredEffectId(), - IsState: false, + "EffectId1".ToEffectId(), + "EffectId1".ToStoredEffectId(isState: false), WorkStatus.Started, Result: "some result 1".ToUtf8Bytes(), StoredException: null ); var storedEffect2 = new StoredEffect( - "EffectId2", - "EffectId2".ToStoredEffectId(), - IsState: false, + "EffectId2".ToEffectId(), + "EffectId2".ToStoredEffectId(isState: false), WorkStatus.Completed, Result: "some result 2".ToUtf8Bytes(), StoredException: null diff --git a/Core/Cleipnir.ResilientFunctions.Tests/TestTemplates/RFunctionTests/ControlPanelTests.cs b/Core/Cleipnir.ResilientFunctions.Tests/TestTemplates/RFunctionTests/ControlPanelTests.cs index 604fc90d..dc576346 100644 --- a/Core/Cleipnir.ResilientFunctions.Tests/TestTemplates/RFunctionTests/ControlPanelTests.cs +++ b/Core/Cleipnir.ResilientFunctions.Tests/TestTemplates/RFunctionTests/ControlPanelTests.cs @@ -1283,9 +1283,8 @@ protected async Task EffectsAreOnlyFetchedOnPropertyInvocation(Task stor await store.EffectsStore.SetEffectResult( rAction.MapToStoredId(functionId), new StoredEffect( - new EffectId("SomeId"), - "SomeId".ToStoredEffectId(), - IsState: false, + new EffectId("SomeId", IsState: false), + "SomeId".ToStoredEffectId(isState: false), WorkStatus.Completed, Result: "SomeResult".ToJson().ToUtf8Bytes(), StoredException: null @@ -1362,7 +1360,7 @@ protected async Task EffectsAreUpdatedAfterRefresh(Task storeTas await secondControlPanel.Refresh(); await secondControlPanel.Effects.GetValue("Id").ShouldBeAsync("SomeResult"); - await secondControlPanel.Effects.GetStatus("Id").ShouldBeAsync(WorkStatus.Completed); + await secondControlPanel.Effects.GetStatus("Id".ToEffectId(isState: false)).ShouldBeAsync(WorkStatus.Completed); unhandledExceptionCatcher.ShouldNotHaveExceptions(); } diff --git a/Core/Cleipnir.ResilientFunctions.Tests/TestTemplates/RFunctionTests/CrashedTests.cs b/Core/Cleipnir.ResilientFunctions.Tests/TestTemplates/RFunctionTests/CrashedTests.cs index 6e9e6b46..a78887ef 100644 --- a/Core/Cleipnir.ResilientFunctions.Tests/TestTemplates/RFunctionTests/CrashedTests.cs +++ b/Core/Cleipnir.ResilientFunctions.Tests/TestTemplates/RFunctionTests/CrashedTests.cs @@ -128,7 +128,7 @@ await store storedFunction.ShouldNotBeNull(); storedFunction.Status.ShouldBe(Status.Succeeded); var effects = await store.EffectsStore.GetEffectResults(registration.MapToStoredId(functionId)); - var stateResult = effects.Single(e => e.EffectId == "State").Result!; + var stateResult = effects.Single(e => e.EffectId == "State".ToEffectId(isState: true)).Result!; stateResult.ShouldNotBeNull(); stateResult.ToStringFromUtf8Bytes().DeserializeFromJsonTo().Value.ShouldBe(1); await rFunc(flowInstance.Value, param).ShouldBeAsync("TEST"); @@ -252,7 +252,7 @@ await store storedFunction.ShouldNotBeNull(); storedFunction.Status.ShouldBe(Status.Succeeded); var effects = await store.EffectsStore.GetEffectResults(registration.MapToStoredId(functionId)); - var state = effects.Single(e => e.EffectId == "State").Result; + var state = effects.Single(e => e.EffectId == "State".ToEffectId(isState: true)).Result; state!.ToStringFromUtf8Bytes().DeserializeFromJsonTo().Value.ShouldBe(1); await rAction(flowInstance.Value, param); } diff --git a/Core/Cleipnir.ResilientFunctions.Tests/TestTemplates/RFunctionTests/EffectImplicitIdTests.cs b/Core/Cleipnir.ResilientFunctions.Tests/TestTemplates/RFunctionTests/EffectImplicitIdTests.cs index a1b8c44e..97f78e4b 100644 --- a/Core/Cleipnir.ResilientFunctions.Tests/TestTemplates/RFunctionTests/EffectImplicitIdTests.cs +++ b/Core/Cleipnir.ResilientFunctions.Tests/TestTemplates/RFunctionTests/EffectImplicitIdTests.cs @@ -37,14 +37,14 @@ await BusyWait.Until(() => syncedCounter.Current.ShouldBe(1); var effectResults = await store.EffectsStore.GetEffectResults(rAction.MapToStoredId(flowId)); - effectResults.Single(r => r.EffectId == "0").WorkStatus.ShouldBe(WorkStatus.Completed); + effectResults.Single(r => r.EffectId == "0".ToEffectId()).WorkStatus.ShouldBe(WorkStatus.Completed); var controlPanel = await rAction.ControlPanel(flowId.Instance); controlPanel.ShouldNotBeNull(); await controlPanel.Restart(); effectResults = await store.EffectsStore.GetEffectResults(rAction.MapToStoredId(flowId)); - effectResults.Single(r => r.EffectId == "0").WorkStatus.ShouldBe(WorkStatus.Completed); + effectResults.Single(r => r.EffectId == "0".ToEffectId()).WorkStatus.ShouldBe(WorkStatus.Completed); syncedCounter.Current.ShouldBe(1); } @@ -72,14 +72,14 @@ await BusyWait.Until(() => syncedCounter.Current.ShouldBe(1); var effectResults = await store.EffectsStore.GetEffectResults(rAction.MapToStoredId(flowId)); - effectResults.Single(r => r.EffectId == "0").WorkStatus.ShouldBe(WorkStatus.Completed); + effectResults.Single(r => r.EffectId == "0".ToEffectId()).WorkStatus.ShouldBe(WorkStatus.Completed); var controlPanel = await rAction.ControlPanel(flowId.Instance); controlPanel.ShouldNotBeNull(); await controlPanel.Restart(); effectResults = await store.EffectsStore.GetEffectResults(rAction.MapToStoredId(flowId)); - effectResults.Single(r => r.EffectId == "0").WorkStatus.ShouldBe(WorkStatus.Completed); + effectResults.Single(r => r.EffectId == "0".ToEffectId()).WorkStatus.ShouldBe(WorkStatus.Completed); syncedCounter.Current.ShouldBe(1); } @@ -112,7 +112,7 @@ await BusyWait.Until(() => syncedCounter.Current.ShouldBe(1); var effectResults = await store.EffectsStore.GetEffectResults(rAction.MapToStoredId(flowId)); - var storedEffect = effectResults.Single(r => r.EffectId == "0"); + var storedEffect = effectResults.Single(r => r.EffectId == "0".ToEffectId()); storedEffect.WorkStatus.ShouldBe(WorkStatus.Completed); storedEffect.Result!.ToStringFromUtf8Bytes().DeserializeFromJsonTo().ShouldBe("hello"); @@ -121,7 +121,7 @@ await BusyWait.Until(() => await controlPanel.Restart(); effectResults = await store.EffectsStore.GetEffectResults(rAction.MapToStoredId(flowId)); - storedEffect = effectResults.Single(r => r.EffectId == "0"); + storedEffect = effectResults.Single(r => r.EffectId == "0".ToEffectId()); storedEffect.WorkStatus.ShouldBe(WorkStatus.Completed); storedEffect.Result!.ToStringFromUtf8Bytes().DeserializeFromJsonTo().ShouldBe("hello"); syncedCounter.Current.ShouldBe(1); @@ -156,7 +156,7 @@ await BusyWait.Until(() => syncedCounter.Current.ShouldBe(1); var effectResults = await store.EffectsStore.GetEffectResults(rAction.MapToStoredId(flowId)); - var storedEffect = effectResults.Single(r => r.EffectId == "0"); + var storedEffect = effectResults.Single(r => r.EffectId == "0".ToEffectId()); storedEffect.WorkStatus.ShouldBe(WorkStatus.Completed); storedEffect.Result!.ToStringFromUtf8Bytes().DeserializeFromJsonTo().ShouldBe("hello"); @@ -165,7 +165,7 @@ await BusyWait.Until(() => await controlPanel.Restart(); effectResults = await store.EffectsStore.GetEffectResults(rAction.MapToStoredId(flowId)); - storedEffect = effectResults.Single(r => r.EffectId == "0"); + storedEffect = effectResults.Single(r => r.EffectId == "0".ToEffectId()); storedEffect.WorkStatus.ShouldBe(WorkStatus.Completed); storedEffect.Result!.ToStringFromUtf8Bytes().DeserializeFromJsonTo().ShouldBe("hello"); syncedCounter.Current.ShouldBe(1); @@ -200,7 +200,7 @@ await BusyWait.Until(() => syncedCounter.Current.ShouldBe(1); var effectResults = await store.EffectsStore.GetEffectResults(rAction.MapToStoredId(flowId)); - var storedEffect = effectResults.Single(r => r.EffectId == "0"); + var storedEffect = effectResults.Single(r => r.EffectId == "0".ToEffectId()); storedEffect.WorkStatus.ShouldBe(WorkStatus.Failed); storedEffect.StoredException.ShouldNotBeNull(); storedEffect.StoredException.ExceptionType.ShouldContain("InvalidOperationException"); @@ -210,7 +210,7 @@ await BusyWait.Until(() => await Should.ThrowAsync(() => controlPanel.Restart()); effectResults = await store.EffectsStore.GetEffectResults(rAction.MapToStoredId(flowId)); - storedEffect = effectResults.Single(r => r.EffectId == "0"); + storedEffect = effectResults.Single(r => r.EffectId == "0".ToEffectId()); storedEffect.WorkStatus.ShouldBe(WorkStatus.Failed); storedEffect.StoredException.ShouldNotBeNull(); storedEffect.StoredException.ExceptionType.ShouldContain("InvalidOperationException"); @@ -238,7 +238,7 @@ async Task (string param, Workflow workflow) => result.ShouldBe(2); var effectResults = await store.EffectsStore.GetEffectResults(rAction.MapToStoredId(flowId)); - var storedEffect = effectResults.Single(r => r.EffectId == "0"); + var storedEffect = effectResults.Single(r => r.EffectId == "0".ToEffectId()); storedEffect.WorkStatus.ShouldBe(WorkStatus.Completed); storedEffect.Result!.ToStringFromUtf8Bytes().DeserializeFromJsonTo().ShouldBe(2); } @@ -264,7 +264,7 @@ async Task (string param, Workflow workflow) => result.ShouldBe(new [] { 1, 2 }); var effectResults = await store.EffectsStore.GetEffectResults(rAction.MapToStoredId(flowId)); - var storedEffect = effectResults.Single(r => r.EffectId == "0"); + var storedEffect = effectResults.Single(r => r.EffectId == "0".ToEffectId()); storedEffect.WorkStatus.ShouldBe(WorkStatus.Completed); storedEffect.Result!.ToStringFromUtf8Bytes().DeserializeFromJsonTo().ShouldBe(new [] {1, 2}); } @@ -296,8 +296,8 @@ async Task(string _, Workflow workflow) => var effects = controlPanel.Effects; var effectIds = (await effects.AllIds).ToList(); effectIds.Count.ShouldBe(2); - effectIds.Any(id => id == "0").ShouldBeTrue(); - effectIds.Any(id => id == "1").ShouldBeTrue(); + effectIds.Any(id => id == "0".ToEffectId()).ShouldBeTrue(); + effectIds.Any(id => id == "1".ToEffectId()).ShouldBeTrue(); await effects.GetValue("0").ShouldBeAsync("0"); await effects.GetValue("1").ShouldBeAsync("1"); diff --git a/Core/Cleipnir.ResilientFunctions.Tests/TestTemplates/RFunctionTests/EffectTests.cs b/Core/Cleipnir.ResilientFunctions.Tests/TestTemplates/RFunctionTests/EffectTests.cs index 186afbcf..2dd9f288 100644 --- a/Core/Cleipnir.ResilientFunctions.Tests/TestTemplates/RFunctionTests/EffectTests.cs +++ b/Core/Cleipnir.ResilientFunctions.Tests/TestTemplates/RFunctionTests/EffectTests.cs @@ -43,14 +43,14 @@ await BusyWait.Until(() => syncedCounter.Current.ShouldBe(1); var effectResults = await store.EffectsStore.GetEffectResults(storedId); - effectResults.Single(r => r.EffectId == "Test").WorkStatus.ShouldBe(WorkStatus.Completed); + effectResults.Single(r => r.EffectId == "Test".ToEffectId()).WorkStatus.ShouldBe(WorkStatus.Completed); var controlPanel = await rAction.ControlPanel(flowId.Instance); controlPanel.ShouldNotBeNull(); await controlPanel.Restart(); effectResults = await store.EffectsStore.GetEffectResults(storedId); - effectResults.Single(r => r.EffectId == "Test").WorkStatus.ShouldBe(WorkStatus.Completed); + effectResults.Single(r => r.EffectId == "Test".ToEffectId()).WorkStatus.ShouldBe(WorkStatus.Completed); syncedCounter.Current.ShouldBe(1); } @@ -81,14 +81,14 @@ await BusyWait.Until(() => syncedCounter.Current.ShouldBe(1); var effectResults = await store.EffectsStore.GetEffectResults(storedId); - effectResults.Single(r => r.EffectId == "Test").WorkStatus.ShouldBe(WorkStatus.Completed); + effectResults.Single(r => r.EffectId == "Test".ToEffectId()).WorkStatus.ShouldBe(WorkStatus.Completed); var controlPanel = await rAction.ControlPanel(flowId.Instance); controlPanel.ShouldNotBeNull(); await controlPanel.Restart(); effectResults = await store.EffectsStore.GetEffectResults(storedId); - effectResults.Single(r => r.EffectId == "Test").WorkStatus.ShouldBe(WorkStatus.Completed); + effectResults.Single(r => r.EffectId == "Test".ToEffectId()).WorkStatus.ShouldBe(WorkStatus.Completed); syncedCounter.Current.ShouldBe(1); } @@ -123,7 +123,7 @@ await BusyWait.Until(() => syncedCounter.Current.ShouldBe(1); var effectResults = await store.EffectsStore.GetEffectResults(storedId); - var storedEffect = effectResults.Single(r => r.EffectId == "Test"); + var storedEffect = effectResults.Single(r => r.EffectId == "Test".ToEffectId()); storedEffect.WorkStatus.ShouldBe(WorkStatus.Completed); storedEffect.Result!.ToStringFromUtf8Bytes().DeserializeFromJsonTo().ShouldBe("hello"); @@ -132,7 +132,7 @@ await BusyWait.Until(() => await controlPanel.Restart(); effectResults = await store.EffectsStore.GetEffectResults(storedId); - storedEffect = effectResults.Single(r => r.EffectId == "Test"); + storedEffect = effectResults.Single(r => r.EffectId == "Test".ToEffectId()); storedEffect.WorkStatus.ShouldBe(WorkStatus.Completed); storedEffect.Result!.ToStringFromUtf8Bytes().DeserializeFromJsonTo().ShouldBe("hello"); syncedCounter.Current.ShouldBe(1); @@ -169,7 +169,7 @@ await BusyWait.Until(() => syncedCounter.Current.ShouldBe(1); var effectResults = await store.EffectsStore.GetEffectResults(storedId); - var storedEffect = effectResults.Single(r => r.EffectId == "Test"); + var storedEffect = effectResults.Single(r => r.EffectId == "Test".ToEffectId()); storedEffect.WorkStatus.ShouldBe(WorkStatus.Completed); storedEffect.Result!.ToStringFromUtf8Bytes().DeserializeFromJsonTo().ShouldBe("hello"); @@ -178,7 +178,7 @@ await BusyWait.Until(() => await controlPanel.Restart(); effectResults = await store.EffectsStore.GetEffectResults(storedId); - storedEffect = effectResults.Single(r => r.EffectId == "Test"); + storedEffect = effectResults.Single(r => r.EffectId == "Test".ToEffectId()); storedEffect.WorkStatus.ShouldBe(WorkStatus.Completed); storedEffect.Result!.ToStringFromUtf8Bytes().DeserializeFromJsonTo().ShouldBe("hello"); syncedCounter.Current.ShouldBe(1); @@ -215,7 +215,7 @@ await BusyWait.Until(() => syncedCounter.Current.ShouldBe(1); var effectResults = await store.EffectsStore.GetEffectResults(storedId); - var storedEffect = effectResults.Single(r => r.EffectId == "Test"); + var storedEffect = effectResults.Single(r => r.EffectId == "Test".ToEffectId()); storedEffect.WorkStatus.ShouldBe(WorkStatus.Failed); storedEffect.StoredException.ShouldNotBeNull(); storedEffect.StoredException.ExceptionType.ShouldContain("InvalidOperationException"); @@ -225,7 +225,7 @@ await BusyWait.Until(() => await Should.ThrowAsync(() => controlPanel.Restart()); effectResults = await store.EffectsStore.GetEffectResults(storedId); - storedEffect = effectResults.Single(r => r.EffectId == "Test"); + storedEffect = effectResults.Single(r => r.EffectId == "Test".ToEffectId()); storedEffect.WorkStatus.ShouldBe(WorkStatus.Failed); storedEffect.StoredException.ShouldNotBeNull(); storedEffect.StoredException.ExceptionType.ShouldContain("InvalidOperationException"); @@ -254,7 +254,7 @@ async Task (string param, Workflow workflow) => var storedId = rAction.MapToStoredId(flowId); var effectResults = await store.EffectsStore.GetEffectResults(storedId); - var storedEffect = effectResults.Single(r => r.EffectId == "WhenAny"); + var storedEffect = effectResults.Single(r => r.EffectId == "WhenAny".ToEffectId()); storedEffect.WorkStatus.ShouldBe(WorkStatus.Completed); storedEffect.Result!.ToStringFromUtf8Bytes().DeserializeFromJsonTo().ShouldBe(2); } @@ -281,7 +281,7 @@ async Task (string param, Workflow workflow) => var storedId = rAction.MapToStoredId(flowId); var effectResults = await store.EffectsStore.GetEffectResults(storedId); - var storedEffect = effectResults.Single(r => r.EffectId == "WhenAll"); + var storedEffect = effectResults.Single(r => r.EffectId == "WhenAll".ToEffectId()); storedEffect.WorkStatus.ShouldBe(WorkStatus.Completed); storedEffect.Result!.ToStringFromUtf8Bytes().DeserializeFromJsonTo().ShouldBe(new [] {1, 2}); } diff --git a/Core/Cleipnir.ResilientFunctions.Tests/TestTemplates/RFunctionTests/PostponedTests.cs b/Core/Cleipnir.ResilientFunctions.Tests/TestTemplates/RFunctionTests/PostponedTests.cs index dc95766b..923049bc 100644 --- a/Core/Cleipnir.ResilientFunctions.Tests/TestTemplates/RFunctionTests/PostponedTests.cs +++ b/Core/Cleipnir.ResilientFunctions.Tests/TestTemplates/RFunctionTests/PostponedTests.cs @@ -137,7 +137,7 @@ await BusyWait.Until( storedFunction.ShouldNotBeNull(); var states = await store.EffectsStore.GetEffectResults(rFunc.MapToStoredId(functionId)); - var state = states.Single(e => e.EffectId == "State"); + var state = states.Single(e => e.EffectId == "State".ToEffectId(isState: true)); state.Result!.ToStringFromUtf8Bytes().DeserializeFromJsonTo().Value.ShouldBe(1); await rFunc.Invoke(param, param).ShouldBeAsync("TEST"); @@ -244,7 +244,7 @@ await Should.ThrowAsync(() => storedFunction.ShouldNotBeNull(); var states = await store.EffectsStore.GetEffectResults(rFunc.MapToStoredId(functionId)); - var state = states.Single(e => e.EffectId == "State"); + var state = states.Single(e => e.EffectId == "State".ToEffectId(isState: true)); state.Result!.ToStringFromUtf8Bytes().DeserializeFromJsonTo().Value.ShouldBe(1); await rFunc.Invoke(flowInstance.Value, param); diff --git a/Core/Cleipnir.ResilientFunctions.Tests/TestTemplates/RFunctionTests/ScheduleReInvocationTests.cs b/Core/Cleipnir.ResilientFunctions.Tests/TestTemplates/RFunctionTests/ScheduleReInvocationTests.cs index eeafc018..1bdc5529 100644 --- a/Core/Cleipnir.ResilientFunctions.Tests/TestTemplates/RFunctionTests/ScheduleReInvocationTests.cs +++ b/Core/Cleipnir.ResilientFunctions.Tests/TestTemplates/RFunctionTests/ScheduleReInvocationTests.cs @@ -114,7 +114,7 @@ await BusyWait.Until( function.ShouldNotBeNull(); function.Status.ShouldBe(Status.Succeeded); var states = await store.EffectsStore.GetEffectResults(rAction.MapToStoredId(functionId)); - var state = states.Single(e => e.EffectId == "State").Result!.ToStringFromUtf8Bytes().DeserializeFromJsonTo>(); + var state = states.Single(e => e.EffectId == "State".ToEffectId(isState: true)).Result!.ToStringFromUtf8Bytes().DeserializeFromJsonTo>(); state.List.Single().ShouldBe("world"); unhandledExceptionCatcher.ShouldNotHaveExceptions(); @@ -220,7 +220,7 @@ await BusyWait.Until( function.Status.ShouldBe(Status.Succeeded); function.Result!.ToStringFromUtf8Bytes().DeserializeFromJsonTo().ShouldBe("something"); var states = await store.EffectsStore.GetEffectResults(rFunc.MapToStoredId(functionId)); - var state = states.Single(e => e.EffectId == "State").Result!.ToStringFromUtf8Bytes().DeserializeFromJsonTo>(); + var state = states.Single(e => e.EffectId == "State".ToEffectId(isState: true)).Result!.ToStringFromUtf8Bytes().DeserializeFromJsonTo>(); state.List.Single().ShouldBe("world"); unhandledExceptionCatcher.ShouldNotHaveExceptions(); diff --git a/Core/Cleipnir.ResilientFunctions.Tests/TestTemplates/RFunctionTests/SunshineTests.cs b/Core/Cleipnir.ResilientFunctions.Tests/TestTemplates/RFunctionTests/SunshineTests.cs index 8c129980..3453ce09 100644 --- a/Core/Cleipnir.ResilientFunctions.Tests/TestTemplates/RFunctionTests/SunshineTests.cs +++ b/Core/Cleipnir.ResilientFunctions.Tests/TestTemplates/RFunctionTests/SunshineTests.cs @@ -264,7 +264,7 @@ await store .ShouldNotBeNullAsync(); var states = await store.EffectsStore.GetEffectResults(reg.MapToStoredId(functionId)); - var state = states.Single(e => e.EffectId == "State").Result!.ToStringFromUtf8Bytes().DeserializeFromJsonTo>(); + var state = states.Single(e => e.EffectId == "State".ToEffectId(isState: true)).Result!.ToStringFromUtf8Bytes().DeserializeFromJsonTo>(); state.List.Single().ShouldBe("hello world"); } diff --git a/Core/Cleipnir.ResilientFunctions.Tests/TestTemplates/ResilientFunctionStateTests.cs b/Core/Cleipnir.ResilientFunctions.Tests/TestTemplates/ResilientFunctionStateTests.cs index 92fd3d57..ee43ece5 100644 --- a/Core/Cleipnir.ResilientFunctions.Tests/TestTemplates/ResilientFunctionStateTests.cs +++ b/Core/Cleipnir.ResilientFunctions.Tests/TestTemplates/ResilientFunctionStateTests.cs @@ -12,7 +12,6 @@ namespace Cleipnir.ResilientFunctions.Tests.TestTemplates { public abstract class ResilientFunctionStateTests { - private readonly DefaultSerializer _serializer = DefaultSerializer.Instance; public abstract Task SunshineScenario(); public async Task SunshineScenario(IFunctionStore store) { @@ -46,7 +45,7 @@ async Task ToUpper(string s, Workflow workflow) storedResult.ShouldBe("HELLO"); var effects = await store.EffectsStore.GetEffectResults(registration.MapToStoredId(functionId)); effects - .Single(e => e.EffectId == "Scrap") + .Single(e => e.EffectId == "Scrap".ToEffectId()) .Result! .ToStringFromUtf8Bytes() .DeserializeFromJsonTo() diff --git a/Core/Cleipnir.ResilientFunctions.Tests/TestTemplates/StatesStoreTests.cs b/Core/Cleipnir.ResilientFunctions.Tests/TestTemplates/StatesStoreTests.cs index 60a6b0d1..da6064b9 100644 --- a/Core/Cleipnir.ResilientFunctions.Tests/TestTemplates/StatesStoreTests.cs +++ b/Core/Cleipnir.ResilientFunctions.Tests/TestTemplates/StatesStoreTests.cs @@ -1,5 +1,6 @@ using System.Linq; using System.Threading.Tasks; +using Cleipnir.ResilientFunctions.Domain; using Cleipnir.ResilientFunctions.Helpers; using Cleipnir.ResilientFunctions.Storage; using Cleipnir.ResilientFunctions.Tests.Utils; @@ -30,19 +31,17 @@ await statesStore.SetEffectResult( var states = await statesStore.GetEffectResults(flowId); states.Count.ShouldBe(2); - var state1 = states.Single(s => s.EffectId == "Id#1"); - state1.IsState.ShouldBeTrue(); + var state1 = states.Single(s => s.EffectId == "Id#1".ToEffectId(isState: true)); state1.Result.ShouldBe("SomeJson#1".ToUtf8Bytes()); - var state2 = states.Single(s => s.EffectId == "Id#2"); - state2.IsState.ShouldBeTrue(); + var state2 = states.Single(s => s.EffectId == "Id#2".ToEffectId(isState: true)); state2.Result.ShouldBe("SomeJson#2".ToUtf8Bytes()); await statesStore.DeleteEffectResult(flowId, state1.EffectId.ToStoredEffectId(), isState: true); states = await statesStore.GetEffectResults(flowId); states.Count.ShouldBe(1); - state2 = states.Single(s => s.EffectId == "Id#2"); + state2 = states.Single(s => s.EffectId == "Id#2".ToEffectId(isState: true)); state2.Result.ShouldBe("SomeJson#2".ToUtf8Bytes()); } } \ No newline at end of file diff --git a/Core/Cleipnir.ResilientFunctions.Tests/TestTemplates/StoreCrudTests.cs b/Core/Cleipnir.ResilientFunctions.Tests/TestTemplates/StoreCrudTests.cs index 643cf99f..540d0907 100644 --- a/Core/Cleipnir.ResilientFunctions.Tests/TestTemplates/StoreCrudTests.cs +++ b/Core/Cleipnir.ResilientFunctions.Tests/TestTemplates/StoreCrudTests.cs @@ -167,7 +167,7 @@ await store.EffectsStore.SetEffectResult( await store.CorrelationStore.SetCorrelation(functionId, "SomeCorrelationId"); await store.EffectsStore.SetEffectResult( functionId, - new StoredEffect("SomeEffectId", "SomeEffectId".ToStoredEffectId(),IsState: false, WorkStatus.Completed, Result: null, StoredException: null) + new StoredEffect("SomeEffectId".ToEffectId(), "SomeEffectId".ToStoredEffectId(isState: false), WorkStatus.Completed, Result: null, StoredException: null) ); await store.MessageStore.AppendMessage(functionId, new StoredMessage("SomeJson".ToUtf8Bytes(), "SomeType".ToUtf8Bytes())); await store.TimeoutStore.UpsertTimeout( diff --git a/Core/Cleipnir.ResilientFunctions.Tests/TestTemplates/StoreTests.cs b/Core/Cleipnir.ResilientFunctions.Tests/TestTemplates/StoreTests.cs index f4886c71..b302de62 100644 --- a/Core/Cleipnir.ResilientFunctions.Tests/TestTemplates/StoreTests.cs +++ b/Core/Cleipnir.ResilientFunctions.Tests/TestTemplates/StoreTests.cs @@ -1108,11 +1108,11 @@ await store.CreateFunction( parent: null ).ShouldBeTrueAsync(); - await effectsStore.SetEffectResult(functionId, new StoredEffect(EffectId: "", "".ToStoredEffectId(), IsState: true, WorkStatus.Completed, "some default state".ToUtf8Bytes(), StoredException: null)); + await effectsStore.SetEffectResult(functionId, new StoredEffect(EffectId: "".ToEffectId(isState: true), "".ToStoredEffectId(isState: true), WorkStatus.Completed, "some default state".ToUtf8Bytes(), StoredException: null)); var storedEffects = await effectsStore.GetEffectResults(functionId); storedEffects.Count.ShouldBe(1); - storedEffects.Single().EffectId.ShouldBe(""); + storedEffects.Single().EffectId.ShouldBe("".ToEffectId(isState: true)); storedEffects.Single().Result.ShouldBe("some default state".ToUtf8Bytes()); } diff --git a/Core/Cleipnir.ResilientFunctions.Tests/TestTemplates/WatchDogsTests/WatchdogCompoundTests.cs b/Core/Cleipnir.ResilientFunctions.Tests/TestTemplates/WatchDogsTests/WatchdogCompoundTests.cs index ebccbdeb..a9945412 100644 --- a/Core/Cleipnir.ResilientFunctions.Tests/TestTemplates/WatchDogsTests/WatchdogCompoundTests.cs +++ b/Core/Cleipnir.ResilientFunctions.Tests/TestTemplates/WatchDogsTests/WatchdogCompoundTests.cs @@ -255,7 +255,7 @@ await store.GetFunction(registration.MapToStoredId(functionId)).Map(sf => sf!.St var storedFunction = await store.GetFunction(registration.MapToStoredId(functionId)); storedFunction!.Result!.ToStringFromUtf8Bytes().DeserializeFromJsonTo().ShouldBe($"{param.Id}-{param.Value}"); var states = await store.EffectsStore.GetEffectResults(registration.MapToStoredId(functionId)); - states.Single(e => e.EffectId == "Scraps") + states.Single(e => e.EffectId == "Scraps".ToEffectId(isState: true)) .Result! .ToStringFromUtf8Bytes() .DeserializeFromJsonTo() @@ -511,7 +511,7 @@ await store.GetFunction(registration.MapToStoredId(functionId)).Map(sf => sf!.St var storedFunction = await store.GetFunction(registration.MapToStoredId(functionId)); var states = await store.EffectsStore.GetEffectResults(registration.MapToStoredId(functionId)); - states.Single(e => e.EffectId == "Scraps") + states.Single(e => e.EffectId == "Scraps".ToEffectId(isState: true)) .Result! .ToStringFromUtf8Bytes() .DeserializeFromJsonTo() diff --git a/Core/Cleipnir.ResilientFunctions/Domain/Effect.cs b/Core/Cleipnir.ResilientFunctions/Domain/Effect.cs index 07e70872..77cca9d6 100644 --- a/Core/Cleipnir.ResilientFunctions/Domain/Effect.cs +++ b/Core/Cleipnir.ResilientFunctions/Domain/Effect.cs @@ -57,15 +57,16 @@ public async Task Contains(string id) var effectResults = await GetEffectResults(); lock (_sync) - return effectResults.ContainsKey(id); + return effectResults.ContainsKey(id.ToEffectId()); } public async Task GetStatus(string id) { + var effectId = id.ToEffectId(); var effectResults = await GetEffectResults(); lock (_sync) - if (effectResults.TryGetValue(id, out var value)) + if (effectResults.TryGetValue(effectId, out var value)) return value.WorkStatus; else return null; @@ -74,14 +75,14 @@ public async Task Contains(string id) public async Task Mark(string id) { var effectResults = await GetEffectResults(); - + var effectId = id.ToEffectId(); lock (_sync) - if (effectResults.ContainsKey(id)) + if (effectResults.ContainsKey(id.ToEffectId())) return false; - var storedEffect = StoredEffect.CreateCompleted(id); + var storedEffect = StoredEffect.CreateCompleted(effectId); await effectsStore.SetEffectResult(storedId, storedEffect); - effectResults[id] = storedEffect; + effectResults[effectId] = storedEffect; return true; } @@ -89,20 +90,21 @@ public async Task Mark(string id) public async Task CreateOrGet(string id, T value) { var effectResults = await GetEffectResults(); + var effectId = id.ToEffectId(); lock (_sync) { - if (effectResults.TryGetValue(id, out var existing) && existing.WorkStatus == WorkStatus.Completed) + if (effectResults.TryGetValue(effectId, out var existing) && existing.WorkStatus == WorkStatus.Completed) return serializer.DeserializeEffectResult(existing.Result!); if (existing?.StoredException != null) throw new EffectException(flowType, id, serializer.DeserializeException(existing.StoredException!)); } - var storedEffect = StoredEffect.CreateCompleted(id, serializer.SerializeEffectResult(value)); + var storedEffect = StoredEffect.CreateCompleted(effectId, serializer.SerializeEffectResult(value)); await effectsStore.SetEffectResult(storedId, storedEffect); lock (_sync) - effectResults[id] = storedEffect; + effectResults[effectId] = storedEffect; return value; } @@ -110,21 +112,23 @@ public async Task CreateOrGet(string id, T value) public async Task Upsert(string id, T value) { var effectResults = await GetEffectResults(); - - var storedEffect = StoredEffect.CreateCompleted(id, serializer.SerializeEffectResult(value)); + var effectId = id.ToEffectId(); + + var storedEffect = StoredEffect.CreateCompleted(effectId, serializer.SerializeEffectResult(value)); await effectsStore.SetEffectResult(storedId, storedEffect); lock (_sync) - effectResults[id] = storedEffect; + effectResults[effectId] = storedEffect; } public async Task> TryGet(string id) { var effectResults = await GetEffectResults(); + var effectId = id.ToEffectId(); lock (_sync) { - if (effectResults.TryGetValue(id, out var storedEffect)) + if (effectResults.TryGetValue(effectId, out var storedEffect)) { if (storedEffect.WorkStatus == WorkStatus.Completed) { @@ -170,9 +174,10 @@ public Task Capture(string id, Func work, ResiliencyLevel resiliency = public async Task Capture(string id, Func work, ResiliencyLevel resiliency = ResiliencyLevel.AtLeastOnce) { var effectResults = await GetEffectResults(); + var effectId = id.ToEffectId(); lock (_sync) { - var success = effectResults.TryGetValue(id, out var storedEffect); + var success = effectResults.TryGetValue(effectId, out var storedEffect); if (success && storedEffect!.WorkStatus == WorkStatus.Completed) return; if (success && storedEffect!.WorkStatus == WorkStatus.Failed) @@ -183,10 +188,10 @@ public async Task Capture(string id, Func work, ResiliencyLevel resiliency if (resiliency == ResiliencyLevel.AtMostOnce) { - var storedEffect = StoredEffect.CreateStarted(id); + var storedEffect = StoredEffect.CreateStarted(effectId); await effectsStore.SetEffectResult(storedId, storedEffect); lock (_sync) - effectResults[id] = storedEffect; + effectResults[effectId] = storedEffect; } try @@ -204,28 +209,29 @@ public async Task Capture(string id, Func work, ResiliencyLevel resiliency catch (Exception exception) { var storedException = serializer.SerializeException(exception); - var storedEffect = StoredEffect.CreateFailed(id, storedException); + var storedEffect = StoredEffect.CreateFailed(effectId, storedException); await effectsStore.SetEffectResult(storedId, storedEffect); lock (_sync) - effectResults[id] = storedEffect; + effectResults[effectId] = storedEffect; throw; } - var effectResult = StoredEffect.CreateCompleted(id); + var effectResult = StoredEffect.CreateCompleted(effectId); await effectsStore.SetEffectResult(storedId,effectResult); lock (_sync) - effectResults[id] = effectResult; + effectResults[effectId] = effectResult; } public async Task Capture(string id, Func> work, ResiliencyLevel resiliency = ResiliencyLevel.AtLeastOnce) { var effectResults = await GetEffectResults(); + var effectId = id.ToEffectId(); lock (_sync) { - var success = effectResults.TryGetValue(id, out var storedEffect); + var success = effectResults.TryGetValue(effectId, out var storedEffect); if (success && storedEffect!.WorkStatus == WorkStatus.Completed) return (storedEffect.Result == null ? default : JsonSerializer.Deserialize(storedEffect.Result))!; if (success && storedEffect!.WorkStatus == WorkStatus.Failed) @@ -236,10 +242,10 @@ public async Task Capture(string id, Func> work, ResiliencyLevel r if (resiliency == ResiliencyLevel.AtMostOnce) { - var storedEffect = StoredEffect.CreateStarted(id); + var storedEffect = StoredEffect.CreateStarted(effectId); await effectsStore.SetEffectResult(storedId, storedEffect); lock (_sync) - effectResults[id] = storedEffect; + effectResults[effectId] = storedEffect; } T result; @@ -258,20 +264,20 @@ public async Task Capture(string id, Func> work, ResiliencyLevel r catch (Exception exception) { var storedException = serializer.SerializeException(exception); - var storedEffect = StoredEffect.CreateFailed(id, storedException); + var storedEffect = StoredEffect.CreateFailed(effectId, storedException); await effectsStore.SetEffectResult(storedId, storedEffect); lock (_sync) - effectResults[id] = storedEffect; + effectResults[effectId] = storedEffect; throw; } - var effectResult = StoredEffect.CreateCompleted(id, serializer.SerializeEffectResult(result)); + var effectResult = StoredEffect.CreateCompleted(effectId, serializer.SerializeEffectResult(result)); await effectsStore.SetEffectResult(storedId, effectResult); lock (_sync) - effectResults[id] = effectResult; + effectResults[effectId] = effectResult; return result; } @@ -279,13 +285,14 @@ public async Task Capture(string id, Func> work, ResiliencyLevel r public async Task Clear(string id) { var effectResults = await GetEffectResults(); + var effectId = id.ToEffectId(); lock (_sync) - if (!effectResults.ContainsKey(id)) + if (!effectResults.ContainsKey(effectId)) return; - await effectsStore.DeleteEffectResult(storedId, id.ToStoredEffectId(), isState: false); + await effectsStore.DeleteEffectResult(storedId, id.ToStoredEffectId(isState: false), isState: false); lock (_sync) - effectResults.Remove(id); + effectResults.Remove(effectId); } public Task WhenAny(string id, params Task[] tasks) diff --git a/Core/Cleipnir.ResilientFunctions/Domain/EffectId.cs b/Core/Cleipnir.ResilientFunctions/Domain/EffectId.cs index 349373d3..99023cec 100644 --- a/Core/Cleipnir.ResilientFunctions/Domain/EffectId.cs +++ b/Core/Cleipnir.ResilientFunctions/Domain/EffectId.cs @@ -1,24 +1,8 @@ -using System; - namespace Cleipnir.ResilientFunctions.Domain; -public class EffectId -{ - public string Value { get; } - public EffectId(string value) - { - ArgumentNullException.ThrowIfNull(value); - Delimiters.EnsureNoUnitSeparator(value); - - Value = value; - } - - public static implicit operator EffectId(string id) => new(id); - public override string ToString() => Value; - public static bool operator ==(EffectId id1, EffectId id2) => id1.Equals(id2); - public static bool operator !=(EffectId id1, EffectId id2) => !(id1 == id2); +public record EffectId(string Value, bool IsState); - public override bool Equals(object? obj) - => obj is EffectId id && id.Value == Value; - public override int GetHashCode() => Value.GetHashCode(); +public static class EffectIdExtensions +{ + public static EffectId ToEffectId(this string value, bool isState = false) => new(value, isState); } \ No newline at end of file diff --git a/Core/Cleipnir.ResilientFunctions/Domain/ExistingEffects.cs b/Core/Cleipnir.ResilientFunctions/Domain/ExistingEffects.cs index c96ea890..4ec54ebf 100644 --- a/Core/Cleipnir.ResilientFunctions/Domain/ExistingEffects.cs +++ b/Core/Cleipnir.ResilientFunctions/Domain/ExistingEffects.cs @@ -23,11 +23,11 @@ private async Task> GetStoredEffects() public Task> AllIds => GetStoredEffects().ContinueWith(t => (IEnumerable) t.Result.Keys); - public async Task HasValue(string effectId) => (await GetStoredEffects()).ContainsKey(effectId); + public async Task HasValue(string effectId) => (await GetStoredEffects()).ContainsKey(new EffectId(effectId, IsState: false)); public async Task GetValue(string effectId) { var storedEffects = await GetStoredEffects(); - var success = storedEffects.TryGetValue(effectId, out var storedEffect); + var success = storedEffects.TryGetValue(new EffectId(effectId, IsState: false), out var storedEffect); if (!success) throw new KeyNotFoundException($"Effect '{effectId}' was not found"); if (storedEffect!.WorkStatus != WorkStatus.Completed) @@ -35,7 +35,7 @@ public Task> AllIds return storedEffect.Result == null ? default - : serializer.DeserializeEffectResult(storedEffects[effectId].Result!); + : serializer.DeserializeEffectResult(storedEffects[new EffectId(effectId, IsState: false)].Result!); } public async Task GetStatus(EffectId effectId) @@ -47,8 +47,8 @@ public async Task GetStatus(EffectId effectId) public async Task Remove(string effectId) { var storedEffects = await GetStoredEffects(); - await effectsStore.DeleteEffectResult(storedId, effectId.ToStoredEffectId(), isState: false); - storedEffects.Remove(effectId); + await effectsStore.DeleteEffectResult(storedId, effectId.ToStoredEffectId(isState: false), isState: false); + storedEffects.Remove(new EffectId(effectId, IsState: false)); } private async Task Set(StoredEffect storedEffect) @@ -61,14 +61,14 @@ private async Task Set(StoredEffect storedEffect) public Task SetValue(string effectId, TValue value) => SetSucceeded(effectId, value); public Task SetStarted(string effectId) - => Set(new StoredEffect(effectId, StoredEffectId.Create(effectId), IsState: false, WorkStatus.Started, Result: null, StoredException: null)); + => Set(new StoredEffect(new EffectId(effectId, IsState: false), StoredEffectId.Create(effectId), WorkStatus.Started, Result: null, StoredException: null)); public Task SetSucceeded(string effectId) - => Set(new StoredEffect(effectId, StoredEffectId.Create(effectId), IsState: false, WorkStatus.Completed, Result: null, StoredException: null)); + => Set(new StoredEffect(new EffectId(effectId, IsState: false), StoredEffectId.Create(effectId), WorkStatus.Completed, Result: null, StoredException: null)); public Task SetSucceeded(string effectId, TResult result) - => Set(new StoredEffect(effectId,StoredEffectId.Create(effectId), IsState: false, WorkStatus.Completed, Result: serializer.SerializeEffectResult(result), StoredException: null)); + => Set(new StoredEffect(new EffectId(effectId, IsState: false),StoredEffectId.Create(effectId), WorkStatus.Completed, Result: serializer.SerializeEffectResult(result), StoredException: null)); public Task SetFailed(string effectId, Exception exception) - => Set(new StoredEffect(effectId, StoredEffectId.Create(effectId), IsState: false, WorkStatus.Failed, Result: null, StoredException: serializer.SerializeException(exception))); + => Set(new StoredEffect(new EffectId(effectId, IsState: false), StoredEffectId.Create(effectId), WorkStatus.Failed, Result: null, StoredException: serializer.SerializeException(exception))); } \ No newline at end of file diff --git a/Core/Cleipnir.ResilientFunctions/Domain/ExistingStates.cs b/Core/Cleipnir.ResilientFunctions/Domain/ExistingStates.cs index 620771db..c3147644 100644 --- a/Core/Cleipnir.ResilientFunctions/Domain/ExistingStates.cs +++ b/Core/Cleipnir.ResilientFunctions/Domain/ExistingStates.cs @@ -28,7 +28,7 @@ private async Task> GetStoredStates() return _storedStates; return _storedStates = (await _functionStore.EffectsStore.GetEffectResults(_storedId)) - .Where(se => se.IsState) + .Where(se => se.EffectId.IsState) .Select(se => new StoredState(se.EffectId.Value, se.Result!)) .ToDictionary(s => s.StateId, s => s); } @@ -56,7 +56,7 @@ private async Task> GetStoredStates() public async Task Remove(string stateId) { var storedStates = await GetStoredStates(); - await _effectsStore.DeleteEffectResult(_storedId, stateId.ToStoredEffectId(), isState: true); + await _effectsStore.DeleteEffectResult(_storedId, stateId.ToStoredEffectId(isState: true), isState: true); storedStates.Remove(stateId); } diff --git a/Core/Cleipnir.ResilientFunctions/Domain/StateFetcher.cs b/Core/Cleipnir.ResilientFunctions/Domain/StateFetcher.cs index ea225868..18ad316e 100644 --- a/Core/Cleipnir.ResilientFunctions/Domain/StateFetcher.cs +++ b/Core/Cleipnir.ResilientFunctions/Domain/StateFetcher.cs @@ -17,7 +17,7 @@ public class StateFetcher(StoredType storedType, IEffectsStore effectsStore, ISe var storedStates = await effectsStore.GetEffectResults(storedId); foreach (var storedEffect in storedStates) - if (storedEffect.EffectId == stateId.Value) + if (storedEffect.EffectId.Value == stateId.Value) { var state = serializer.DeserializeState(storedEffect.Result!); state.Initialize( diff --git a/Core/Cleipnir.ResilientFunctions/Domain/States.cs b/Core/Cleipnir.ResilientFunctions/Domain/States.cs index ed825927..c8a4755b 100644 --- a/Core/Cleipnir.ResilientFunctions/Domain/States.cs +++ b/Core/Cleipnir.ResilientFunctions/Domain/States.cs @@ -26,7 +26,7 @@ private async Task> GetExistingStoredStates() return _existingStoredStates; var existingStatesDict = (await lazyEffects.Value) - .Where(se => se.IsState) + .Where(se => se.EffectId.IsState) .ToDictionary(se => new StateId(se.EffectId.Value), se => new StoredState(se.EffectId.Value, se.Result!)); lock (_sync) @@ -86,7 +86,7 @@ private async Task RemoveInner(string id) if (!existingStoredStates.ContainsKey(id)) return; - await effectStore.DeleteEffectResult(storedId, id.ToStoredEffectId(), isState: true); + await effectStore.DeleteEffectResult(storedId, id.ToStoredEffectId(isState: true), isState: true); lock (_sync) { diff --git a/Core/Cleipnir.ResilientFunctions/Storage/InMemoryEffectsStore.cs b/Core/Cleipnir.ResilientFunctions/Storage/InMemoryEffectsStore.cs index 2fa9caf5..5168524f 100644 --- a/Core/Cleipnir.ResilientFunctions/Storage/InMemoryEffectsStore.cs +++ b/Core/Cleipnir.ResilientFunctions/Storage/InMemoryEffectsStore.cs @@ -25,7 +25,7 @@ public Task SetEffectResult(StoredId storedId, StoredEffect storedEffect) { lock (_sync) { - var key = new EffectKey(storedEffect.StoredEffectId, storedEffect.IsState); + var key = new EffectKey(storedEffect.StoredEffectId, storedEffect.EffectId.IsState); if (!_effects.ContainsKey(storedId)) _effects[storedId] = new Dictionary(); diff --git a/Core/Cleipnir.ResilientFunctions/Storage/Types.cs b/Core/Cleipnir.ResilientFunctions/Storage/Types.cs index fcc0f050..c9c61844 100644 --- a/Core/Cleipnir.ResilientFunctions/Storage/Types.cs +++ b/Core/Cleipnir.ResilientFunctions/Storage/Types.cs @@ -68,29 +68,28 @@ public static StoredEffectId Create(string instanceId) public static class StoredEffectIdExtensions { - public static StoredEffectId ToStoredEffectId(this string effectId) => StoredEffectId.Create(effectId); + public static StoredEffectId ToStoredEffectId(this string effectId, bool isState) => StoredEffectId.Create(effectId); public static StoredEffectId ToStoredEffectId(this EffectId effectId) => StoredEffectId.Create(effectId.Value); } public record StoredEffect( EffectId EffectId, StoredEffectId StoredEffectId, - bool IsState, WorkStatus WorkStatus, byte[]? Result, StoredException? StoredException ) { public static StoredEffect CreateCompleted(EffectId effectId, byte[] result) - => new(effectId, StoredEffectId.Create(effectId.Value), IsState: false, WorkStatus.Completed, result, StoredException: null); + => new(effectId with {IsState = false}, StoredEffectId.Create(effectId.Value), WorkStatus.Completed, result, StoredException: null); public static StoredEffect CreateCompleted(EffectId effectId) - => new(effectId, StoredEffectId.Create(effectId.Value), IsState: false, WorkStatus.Completed, Result: null, StoredException: null); + => new(effectId with {IsState = false}, StoredEffectId.Create(effectId.Value), WorkStatus.Completed, Result: null, StoredException: null); public static StoredEffect CreateStarted(EffectId effectId) - => new(effectId, StoredEffectId.Create(effectId.Value), IsState: false, WorkStatus.Started, Result: null, StoredException: null); + => new(effectId with {IsState = false}, StoredEffectId.Create(effectId.Value), WorkStatus.Started, Result: null, StoredException: null); public static StoredEffect CreateFailed(EffectId effectId, StoredException storedException) - => new(effectId, StoredEffectId.Create(effectId.Value), IsState: false, WorkStatus.Failed, Result: null, storedException); + => new(effectId with {IsState = false}, StoredEffectId.Create(effectId.Value), WorkStatus.Failed, Result: null, storedException); public static StoredEffect CreateState(StoredState storedState) - => new(storedState.StateId.Value, StoredEffectId.Create(storedState.StateId.Value), IsState: true, WorkStatus.Completed, storedState.StateJson, StoredException: null); + => new(new EffectId(storedState.StateId.Value, IsState: true), StoredEffectId.Create(storedState.StateId.Value), WorkStatus.Completed, storedState.StateJson, StoredException: null); }; public record StoredState(StateId StateId, byte[] StateJson); diff --git a/Stores/MariaDB/Cleipnir.ResilientFunctions.MariaDB/MariaDbEffectsStore.cs b/Stores/MariaDB/Cleipnir.ResilientFunctions.MariaDB/MariaDbEffectsStore.cs index f49a2c59..3c413ff6 100644 --- a/Stores/MariaDB/Cleipnir.ResilientFunctions.MariaDB/MariaDbEffectsStore.cs +++ b/Stores/MariaDB/Cleipnir.ResilientFunctions.MariaDB/MariaDbEffectsStore.cs @@ -65,7 +65,7 @@ ON DUPLICATE KEY UPDATE new() {Value = storedId.Type.Value}, new() {Value = storedId.Instance.Value.ToString("N")}, new() {Value = storedEffect.StoredEffectId.Value.ToString("N")}, - new() {Value = storedEffect.IsState}, + new() {Value = storedEffect.EffectId.IsState}, new() {Value = (int) storedEffect.WorkStatus}, new() {Value = storedEffect.Result ?? (object) DBNull.Value}, new() {Value = JsonHelper.ToJson(storedEffect.StoredException) ?? (object) DBNull.Value}, @@ -99,7 +99,7 @@ ON DUPLICATE KEY UPDATE command.Parameters.Add(new MySqlParameter(name: null, storedId.Type.Value)); command.Parameters.Add(new MySqlParameter(name: null, storedId.Instance.Value.ToString("N"))); command.Parameters.Add(new MySqlParameter(name: null, storedEffect.StoredEffectId.Value.ToString("N"))); - command.Parameters.Add(new MySqlParameter(name: null, storedEffect.IsState)); + command.Parameters.Add(new MySqlParameter(name: null, storedEffect.EffectId.IsState)); command.Parameters.Add(new MySqlParameter(name: null, (int) storedEffect.WorkStatus)); command.Parameters.Add(new MySqlParameter(name: null, storedEffect.Result ?? (object) DBNull.Value)); command.Parameters.Add(new MySqlParameter(name: null, JsonHelper.ToJson(storedEffect.StoredException) ?? (object) DBNull.Value)); @@ -139,9 +139,8 @@ public async Task> GetEffectResults(StoredId storedI var effectId = reader.GetString(5); functions.Add( new StoredEffect( - effectId, + new EffectId(effectId, isState), new StoredEffectId(Guid.Parse(idHash)), - isState, status, result, StoredException: JsonHelper.FromJson(exception) diff --git a/Stores/PostgreSQL/Cleipnir.ResilientFunctions.PostgreSQL/PostgreSqlEffectsStore.cs b/Stores/PostgreSQL/Cleipnir.ResilientFunctions.PostgreSQL/PostgreSqlEffectsStore.cs index 6cf75b3a..6122e016 100644 --- a/Stores/PostgreSQL/Cleipnir.ResilientFunctions.PostgreSQL/PostgreSqlEffectsStore.cs +++ b/Stores/PostgreSQL/Cleipnir.ResilientFunctions.PostgreSQL/PostgreSqlEffectsStore.cs @@ -59,7 +59,7 @@ ON CONFLICT (type, instance, id_hash, is_state) new() {Value = storedId.Type.Value}, new() {Value = storedId.Instance.Value}, new() {Value = storedEffect.StoredEffectId.Value}, - new() {Value = storedEffect.IsState}, + new() {Value = storedEffect.EffectId.IsState}, new() {Value = (int) storedEffect.WorkStatus}, new() {Value = storedEffect.Result ?? (object) DBNull.Value}, new() {Value = JsonHelper.ToJson(storedEffect.StoredException) ?? (object) DBNull.Value}, @@ -92,7 +92,7 @@ ON CONFLICT (type, instance, id_hash, is_state) new() {Value = storedId.Type.Value}, new() {Value = storedId.Instance.Value}, new() {Value = storedEffect.StoredEffectId.Value}, - new() {Value = storedEffect.IsState}, + new() {Value = storedEffect.EffectId.IsState}, new() {Value = (int) storedEffect.WorkStatus}, new() {Value = storedEffect.Result ?? (object) DBNull.Value}, new() {Value = JsonHelper.ToJson(storedEffect.StoredException) ?? (object) DBNull.Value}, @@ -135,7 +135,7 @@ public async Task> GetEffectResults(StoredId storedI var exception = reader.IsDBNull(4) ? null : reader.GetString(4); var effectId = reader.GetString(5); functions.Add( - new StoredEffect(effectId, new StoredEffectId(idHash), isState, status, result, JsonHelper.FromJson(exception)) + new StoredEffect(new EffectId(effectId, isState), new StoredEffectId(idHash), status, result, JsonHelper.FromJson(exception)) ); } diff --git a/Stores/SqlServer/Cleipnir.ResilientFunctions.SqlServer/SqlServerEffectsStore.cs b/Stores/SqlServer/Cleipnir.ResilientFunctions.SqlServer/SqlServerEffectsStore.cs index 97116c7a..73e070dc 100644 --- a/Stores/SqlServer/Cleipnir.ResilientFunctions.SqlServer/SqlServerEffectsStore.cs +++ b/Stores/SqlServer/Cleipnir.ResilientFunctions.SqlServer/SqlServerEffectsStore.cs @@ -67,7 +67,7 @@ WHEN NOT MATCHED THEN command.Parameters.AddWithValue("@FlowType", storedId.Type.Value); command.Parameters.AddWithValue("@FlowInstance", storedId.Instance.Value); command.Parameters.AddWithValue("@StoredId", storedEffect.StoredEffectId.Value); - command.Parameters.AddWithValue("@IsState", storedEffect.IsState); + command.Parameters.AddWithValue("@IsState", storedEffect.EffectId.IsState); command.Parameters.AddWithValue("@EffectId", storedEffect.EffectId.Value); command.Parameters.AddWithValue("@Status", storedEffect.WorkStatus); command.Parameters.AddWithValue("@Result", storedEffect.Result ?? (object) SqlBinary.Null); @@ -105,7 +105,7 @@ WHEN NOT MATCHED THEN command.Parameters.AddWithValue($"@FlowType{i}", storedId.Type.Value); command.Parameters.AddWithValue($"@FlowInstance{i}", storedId.Instance.Value); command.Parameters.AddWithValue($"@StoredId{i}", storedEffect.StoredEffectId.Value); - command.Parameters.AddWithValue($"@IsState{i}", storedEffect.IsState); + command.Parameters.AddWithValue($"@IsState{i}", storedEffect.EffectId.IsState); command.Parameters.AddWithValue($"@EffectId{i}", storedEffect.EffectId.Value); command.Parameters.AddWithValue($"@Status{i}", storedEffect.WorkStatus); command.Parameters.AddWithValue($"@Result{i}", storedEffect.Result ?? (object) SqlBinary.Null); @@ -141,7 +141,7 @@ public async Task> GetEffectResults(StoredId storedI var exception = reader.IsDBNull(5) ? default : reader.GetString(5); var storedException = exception == null ? null : JsonSerializer.Deserialize(exception); - var storedEffect = new StoredEffect(effectId, new StoredEffectId(storedEffectId), isState, status, result, storedException); + var storedEffect = new StoredEffect(effectId.ToEffectId(isState), new StoredEffectId(storedEffectId), status, result, storedException); storedEffects.Add(storedEffect); }