Skip to content

Commit

Permalink
Removed IExposeState functionality
Browse files Browse the repository at this point in the history
  • Loading branch information
stidsborg committed Oct 19, 2024
1 parent 6ec889d commit c9ec57c
Show file tree
Hide file tree
Showing 11 changed files with 29 additions and 101 deletions.
44 changes: 21 additions & 23 deletions Cleipnir.Flows.Tests/Flows/FlowsWithStateTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ public async Task ParamlessFlowWithStateCanBeFetchedAfterExecution()
var flows = new ParamlessWithStateFlows(flowsContainer);
await flows.Run("someInstanceId");

var state = await flows.GetState("someInstanceId");
var state = await (await flows.ControlPanel("someInstanceId"))!.States.Get<ParamlessWithStateFlow.WorkflowState>();
state.ShouldNotBeNull();
state.Boolean.ShouldBeTrue();

Expand All @@ -49,15 +49,15 @@ public async Task ActionFlowWithStateCanBeFetchedAfterExecution()
var flows = new ActionWithStateFlows(flowsContainer);
await flows.Run("someInstanceId", "someParameter");

var state = await flows.GetState("someInstanceId");
var state = await (await flows.ControlPanel("someInstanceId"))!.States.Get<ActionWithStateFlow.WorkflowState>();
state.ShouldNotBeNull();
state.Value.ShouldBe("someParameter");

var controlPanel = await flows.ControlPanel(instanceId: "someInstanceId");
controlPanel.ShouldNotBeNull();
controlPanel.Status.ShouldBe(Status.Succeeded);

var flowState = controlPanel.States.Get<FuncWithStateFlow.WorkflowState>();
var flowState = await controlPanel.States.Get<FuncWithStateFlow.WorkflowState>();
flowState.ShouldNotBeNull();
flowState.Value.ShouldBe("someParameter");
}
Expand All @@ -78,7 +78,7 @@ public async Task FuncFlowWithStateCanBeFetchedAfterExecution()
var flows = new FuncWithStateFlows(flowsContainer);
await flows.Run("someInstanceId", "someParameter");

var state = await flows.GetState("someInstanceId");
var state = await (await flows.ControlPanel("someInstanceId"))!.States.Get<FuncWithStateFlow.WorkflowState>();
state.ShouldNotBeNull();
state.Value.ShouldBe("someParameter");

Expand All @@ -87,21 +87,20 @@ public async Task FuncFlowWithStateCanBeFetchedAfterExecution()
controlPanel.Result.ShouldBe("someParameter");
controlPanel.Status.ShouldBe(Status.Succeeded);

var flowState = controlPanel.States.Get<FuncWithStateFlow.WorkflowState>();
var flowState = await controlPanel.States.Get<FuncWithStateFlow.WorkflowState>();
flowState.ShouldNotBeNull();
flowState.Value.ShouldBe("someParameter");
}
}

[GenerateFlows]
public class ActionWithStateFlow : Flow<string>, IExposeState<ActionWithStateFlow.WorkflowState>
public class ActionWithStateFlow : Flow<string>
{
public required WorkflowState State { get; init; }

public override Task Run(string param)
public override async Task Run(string param)
{
State.Value = param;
return Task.CompletedTask;
var state = await Workflow.States.CreateOrGetDefault<WorkflowState>();
state.Value = param;
await state.Save();
}

public class WorkflowState : FlowState
Expand All @@ -111,14 +110,14 @@ public class WorkflowState : FlowState
}

[GenerateFlows]
public class FuncWithStateFlow : Flow<string, string>, IExposeState<FuncWithStateFlow.WorkflowState>
public class FuncWithStateFlow : Flow<string, string>
{
public required WorkflowState State { get; init; }

public override Task<string> Run(string param)
public override async Task<string> Run(string param)
{
State.Value = param;
return Task.FromResult(param);
var state = await Workflow.States.CreateOrGetDefault<WorkflowState>();
state.Value = param;
await state.Save();
return param;
}

public class WorkflowState : FlowState
Expand All @@ -128,14 +127,13 @@ public class WorkflowState : FlowState
}

[GenerateFlows]
public class ParamlessWithStateFlow : Flow, IExposeState<ParamlessWithStateFlow.WorkflowState>
public class ParamlessWithStateFlow : Flow
{
public required WorkflowState State { get; init; }

public override Task Run()
public override async Task Run()
{
State.Boolean = true;
return Task.CompletedTask;
var state = await Workflow.States.CreateOrGetDefault<WorkflowState>();
state.Boolean = true;
await state.Save();
}

public class WorkflowState : FlowState
Expand Down
4 changes: 2 additions & 2 deletions Cleipnir.Flows/CrossCutting/CallChain.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,9 @@ public static Next<TFlow, TParam, TResult> Create<TFlow, TParam, TResult>(
var result = await runFlow(p, w);
return new Result<TResult>(result);
}
catch (SuspendInvocationException suspendInvocationException)
catch (SuspendInvocationException)
{
return new Result<TResult>(Suspend.While(suspendInvocationException.ExpectedInterruptCount.Value));
return new Result<TResult>(Suspend.Invocation);
}
catch (PostponeInvocationException postponeInvocationException)
{
Expand Down
28 changes: 0 additions & 28 deletions Cleipnir.Flows/Flows.cs
Original file line number Diff line number Diff line change
Expand Up @@ -50,38 +50,11 @@ private static Action<TFlow, Workflow> CreateWorkflowSetter()
var setter = lambdaExpr.Compile();
return setter;
}

private static Action<TFlow, States> CreateStateSetter()
{
var iExposeStateType = typeof(TFlow)
.GetInterfaces()
.SingleOrDefault(i => i.IsGenericType && i.GetGenericTypeDefinition() == typeof(IExposeState<>));

if (iExposeStateType == null)
return (_, _) => { };

var stateType = iExposeStateType.GenericTypeArguments[0];

//fetch state
var methodInfo = typeof(States)
.GetMethods()
.Single(m => m.Name == nameof(States.CreateOrGet) && !m.GetParameters().Any());

var genericMethodInfo = methodInfo.MakeGenericMethod(stateType);
var statePropertyInfo = iExposeStateType.GetProperty("State");

return (flow, states) =>
{
var state = genericMethodInfo.Invoke(states, parameters: null);
statePropertyInfo!.SetValue(flow, state);
};
}

protected Next<TFlow, TParam, TResult> CreateMiddlewareCallChain<TParam, TResult>(Func<TFlow, TParam, Task<TResult>> runFlow) where TParam : notnull
{
var serviceProvider = FlowsContainer.ServiceProvider;
var workflowSetter = CreateWorkflowSetter();
var stateSetter = CreateStateSetter();
return CallChain.Create<TFlow, TParam, TResult>(
FlowsContainer.Middlewares,
runFlow: async (param, workflow) =>
Expand All @@ -90,7 +63,6 @@ protected Next<TFlow, TParam, TResult> CreateMiddlewareCallChain<TParam, TResult

var flow = scope.ServiceProvider.GetRequiredService<TFlow>();
workflowSetter(flow, workflow);
stateSetter(flow, workflow.States);

var result = await runFlow(flow, param);
return result;
Expand Down
8 changes: 0 additions & 8 deletions Cleipnir.Flows/IExposeState.cs

This file was deleted.

2 changes: 1 addition & 1 deletion Cleipnir.ResilientFunctions
Submodule Cleipnir.ResilientFunctions updated 87 files
+8 −18 Core/Cleipnir.ResilientFunctions.Tests/InMemoryTests/LeaseUpdaterTests/LeaseUpdaterTestFunctionStore.cs
+0 −2 Core/Cleipnir.ResilientFunctions.Tests/InMemoryTests/RFunctionTests/DelayedStartUpTests.cs
+4 −0 Core/Cleipnir.ResilientFunctions.Tests/InMemoryTests/RFunctionTests/StateTests.cs
+8 −0 Core/Cleipnir.ResilientFunctions.Tests/InMemoryTests/RFunctionTests/SunshineTests.cs
+8 −0 Core/Cleipnir.ResilientFunctions.Tests/InMemoryTests/RFunctionTests/SuspensionTests.cs
+0 −1 Core/Cleipnir.ResilientFunctions.Tests/InMemoryTests/ShutdownCoordinationTests/RFunctionsShutdownTests.cs
+4 −12 Core/Cleipnir.ResilientFunctions.Tests/InMemoryTests/StoreTests.cs
+0 −3 Core/Cleipnir.ResilientFunctions.Tests/Messaging/TestTemplates/CustomMessageSerializerTests.cs
+0 −9 Core/Cleipnir.ResilientFunctions.Tests/Messaging/TestTemplates/MessagesTests.cs
+0 −12 Core/Cleipnir.ResilientFunctions.Tests/Messaging/Utils/TestInterruptCount.cs
+1 −2 Core/Cleipnir.ResilientFunctions.Tests/ReactiveTests/TestSource.cs
+19 −11 Core/Cleipnir.ResilientFunctions.Tests/TestTemplates/EffectStoreTests.cs
+13 −15 Core/Cleipnir.ResilientFunctions.Tests/TestTemplates/RFunctionTests/ControlPanelTests.cs
+5 −5 Core/Cleipnir.ResilientFunctions.Tests/TestTemplates/RFunctionTests/CrashedTests.cs
+1 −1 Core/Cleipnir.ResilientFunctions.Tests/TestTemplates/RFunctionTests/DoubleInvocationTests.cs
+11 −6 Core/Cleipnir.ResilientFunctions.Tests/TestTemplates/RFunctionTests/EffectTests.cs
+6 −7 Core/Cleipnir.ResilientFunctions.Tests/TestTemplates/RFunctionTests/PostponedTests.cs
+4 −4 Core/Cleipnir.ResilientFunctions.Tests/TestTemplates/RFunctionTests/ScheduleReInvocationTests.cs
+32 −2 Core/Cleipnir.ResilientFunctions.Tests/TestTemplates/RFunctionTests/StateTests.cs
+82 −2 Core/Cleipnir.ResilientFunctions.Tests/TestTemplates/RFunctionTests/SunshineTests.cs
+104 −10 Core/Cleipnir.ResilientFunctions.Tests/TestTemplates/RFunctionTests/SuspensionTests.cs
+22 −14 Core/Cleipnir.ResilientFunctions.Tests/TestTemplates/StatesStoreTests.cs
+5 −3 Core/Cleipnir.ResilientFunctions.Tests/TestTemplates/StoreCrudTests.cs
+46 −122 Core/Cleipnir.ResilientFunctions.Tests/TestTemplates/StoreTests.cs
+54 −0 Core/Cleipnir.ResilientFunctions.Tests/TestTemplates/WatchDogsTests/CrashableEffectStore.cs
+35 −33 Core/Cleipnir.ResilientFunctions.Tests/TestTemplates/WatchDogsTests/CrashableFunctionStore.cs
+6 −6 Core/Cleipnir.ResilientFunctions.Tests/TestTemplates/WatchDogsTests/WatchdogCompoundTests.cs
+0 −1 Core/Cleipnir.ResilientFunctions/CoreRuntime/Invocation/FunctionState.cs
+24 −42 Core/Cleipnir.ResilientFunctions/CoreRuntime/Invocation/InvocationHelper.cs
+12 −20 Core/Cleipnir.ResilientFunctions/CoreRuntime/Invocation/Invoker.cs
+1 −3 Core/Cleipnir.ResilientFunctions/CoreRuntime/Invocation/Workflow.cs
+1 −1 Core/Cleipnir.ResilientFunctions/Domain/ControlPanel.cs
+3 −3 Core/Cleipnir.ResilientFunctions/Domain/ControlPanelFactory.cs
+21 −25 Core/Cleipnir.ResilientFunctions/Domain/Effect.cs
+1 −1 Core/Cleipnir.ResilientFunctions/Domain/EffectId.cs
+1 −4 Core/Cleipnir.ResilientFunctions/Domain/Exceptions/Commands/SuspendInvocationException.cs
+5 −5 Core/Cleipnir.ResilientFunctions/Domain/ExistingEffects.cs
+14 −35 Core/Cleipnir.ResilientFunctions/Domain/ExistingStates.cs
+0 −22 Core/Cleipnir.ResilientFunctions/Domain/InterruptCount.cs
+1 −5 Core/Cleipnir.ResilientFunctions/Domain/Result.cs
+8 −30 Core/Cleipnir.ResilientFunctions/Domain/StateFetcher.cs
+29 −43 Core/Cleipnir.ResilientFunctions/Domain/States.cs
+3 −3 Core/Cleipnir.ResilientFunctions/FunctionsRegistry.cs
+14 −15 Core/Cleipnir.ResilientFunctions/InnerAdapters/InnerToAsyncResultAdapters.cs
+1 −1 Core/Cleipnir.ResilientFunctions/Messaging/MessageWriter.cs
+1 −3 Core/Cleipnir.ResilientFunctions/Messaging/MessagesPullerAndEmitter.cs
+3 −14 Core/Cleipnir.ResilientFunctions/Reactive/Extensions/LeafOperators.cs
+0 −1 Core/Cleipnir.ResilientFunctions/Reactive/ISubscription.cs
+0 −2 Core/Cleipnir.ResilientFunctions/Reactive/Operators/BufferOperator.cs
+0 −2 Core/Cleipnir.ResilientFunctions/Reactive/Operators/CustomOperator.cs
+0 −1 Core/Cleipnir.ResilientFunctions/Reactive/Operators/TimeoutOperator.cs
+2 −5 Core/Cleipnir.ResilientFunctions/Reactive/Origin/Source.cs
+1 −4 Core/Cleipnir.ResilientFunctions/Reactive/Origin/SourceSubscription.cs
+2 −2 Core/Cleipnir.ResilientFunctions/Storage/IEffectsStore.cs
+2 −10 Core/Cleipnir.ResilientFunctions/Storage/IFunctionStore.cs
+0 −15 Core/Cleipnir.ResilientFunctions/Storage/IStatesStore.cs
+11 −8 Core/Cleipnir.ResilientFunctions/Storage/InMemoryEffectsStore.cs
+22 −38 Core/Cleipnir.ResilientFunctions/Storage/InMemoryFunctionStore.cs
+0 −69 Core/Cleipnir.ResilientFunctions/Storage/InMemoryStatesStore.cs
+20 −3 Core/Cleipnir.ResilientFunctions/Storage/Types.cs
+1 −1 Samples/Sample.ConsoleApp/EmailOffers/MailSenderSaga.cs
+1 −1 Samples/Sample.ConsoleApp/LoyaltyPoints/LoyaltyPointsFlow.cs
+1 −1 Samples/Sample.ConsoleApp/SmsVerification/SmsVerificationFlow.cs
+14 −30 Samples/Sample.ConsoleApp/Utils/CrashableFunctionStore.cs
+4 −0 Stores/MySQL/Cleipnir.ResilientFunctions.MySQL.Tests/RFunctionTests/StateTests.cs
+8 −0 Stores/MySQL/Cleipnir.ResilientFunctions.MySQL.Tests/RFunctionTests/SunshineTests.cs
+8 −0 Stores/MySQL/Cleipnir.ResilientFunctions.MySQL.Tests/RFunctionTests/SuspensionTests.cs
+5 −13 Stores/MySQL/Cleipnir.ResilientFunctions.MySQL.Tests/StoreTests.cs
+29 −13 Stores/MySQL/Cleipnir.ResilientFunctions.MySQL/MySqlEffectsStore.cs
+48 −78 Stores/MySQL/Cleipnir.ResilientFunctions.MySQL/MySqlFunctionStore.cs
+0 −130 Stores/MySQL/Cleipnir.ResilientFunctions.MySQL/MySqlStatesStore.cs
+4 −0 Stores/PostgreSQL/Cleipnir.ResilientFunctions.PostgreSQL.Tests/RFunctionTests/StateTests.cs
+8 −0 Stores/PostgreSQL/Cleipnir.ResilientFunctions.PostgreSQL.Tests/RFunctionTests/SunshineTests.cs
+8 −0 Stores/PostgreSQL/Cleipnir.ResilientFunctions.PostgreSQL.Tests/RFunctionTests/SuspensionTests.cs
+4 −12 Stores/PostgreSQL/Cleipnir.ResilientFunctions.PostgreSQL.Tests/StoreTests.cs
+23 −15 Stores/PostgreSQL/Cleipnir.ResilientFunctions.PostgreSQL/PostgreSqlEffectsStore.cs
+64 −89 Stores/PostgreSQL/Cleipnir.ResilientFunctions.PostgreSQL/PostgreSqlFunctionStore.cs
+3 −4 Stores/PostgreSQL/Cleipnir.ResilientFunctions.PostgreSQL/PostgreSqlMessageStore.cs
+0 −127 Stores/PostgreSQL/Cleipnir.ResilientFunctions.PostgreSQL/PostgreSqlStatesStore.cs
+4 −0 Stores/SqlServer/Cleipnir.ResilientFunctions.SqlServer.Tests/RFunctionTests/StateTests.cs
+8 −0 Stores/SqlServer/Cleipnir.ResilientFunctions.SqlServer.Tests/RFunctionTests/SunshineTests.cs
+8 −0 Stores/SqlServer/Cleipnir.ResilientFunctions.SqlServer.Tests/RFunctionTests/SuspensionTests.cs
+5 −13 Stores/SqlServer/Cleipnir.ResilientFunctions.SqlServer.Tests/StoreTests.cs
+20 −15 Stores/SqlServer/Cleipnir.ResilientFunctions.SqlServer/SqlServerEffectsStore.cs
+54 −75 Stores/SqlServer/Cleipnir.ResilientFunctions.SqlServer/SqlServerFunctionStore.cs
+0 −136 Stores/SqlServer/Cleipnir.ResilientFunctions.SqlServer/SqlServerStatesStore.cs
+0 −1 Stores/StressTests/StressTests/PostponedTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
namespace Cleipnir.Flows.Sample.Presentation.C_NewsletterSender.Solution;

[GenerateFlows]
public class NewsletterFlow : Flow<MailAndRecipients>, IExposeState<NewsletterFlow.NewsletterState>
public class NewsletterFlow : Flow<MailAndRecipients>
{
public required NewsletterState State { get; init; }

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
namespace Cleipnir.Flows.Sample.Presentation.F_SmsVerificationFlow;

[GenerateFlows]
public class SmsFlow : Flow<string>, IExposeState<SmsFlow.SmsState>
public class SmsFlow : Flow<string>
{
public required SmsState State { get; init; }

Expand Down
2 changes: 1 addition & 1 deletion Samples/Cleipnir.Flows.Samples.Console/State/StateFlow.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
namespace Cleipnir.Flows.Sample.ConsoleApp.State;

[GenerateFlows]
public class StateFlow : Flow<string, string>, IExposeState<StateFlow.WorkflowState>
public class StateFlow : Flow<string, string>
{
public required WorkflowState State { get; init; }

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ internal class FlowInformation
public ITypeSymbol? ParamTypeSymbol { get; }
public string? ParameterName { get; }
public ITypeSymbol? ResultTypeSymbol { get; }
public ITypeSymbol? StateTypeSymbol { get; }
public bool Paramless { get; }
public string AccessibilityModifier { get; }

Expand All @@ -17,15 +16,13 @@ public FlowInformation(
ITypeSymbol? paramType,
string? parameterName,
ITypeSymbol? resultType,
ITypeSymbol? stateTypeSymbol,
bool paramless,
string accessibilityModifier)
{
FlowTypeSymbol = flowType;
ParamTypeSymbol = paramType;
ParameterName = parameterName;
ResultTypeSymbol = resultType;
StateTypeSymbol = stateTypeSymbol;
Paramless = paramless;
AccessibilityModifier = accessibilityModifier;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,11 @@ public class FlowsSourceGenerator : IIncrementalGenerator
private const string ParamlessFlowType = "Cleipnir.Flows.Flow";
private const string UnitFlowType = "Cleipnir.Flows.Flow`1";
private const string ResultFlowType = "Cleipnir.Flows.Flow`2";
private const string IExposeStateType = "Cleipnir.Flows.IExposeState`1";
private const string IgnoreAttribute = "Cleipnir.Flows.SourceGeneration.Ignore";

private INamedTypeSymbol? _paramlessFlowTypeSymbol;
private INamedTypeSymbol? _unitFlowTypeSymbol;
private INamedTypeSymbol? _resultFlowTypeSymbol;
private INamedTypeSymbol? _exposeStateTypeSymbol;
private INamedTypeSymbol? _ignoreAttribute;

public void Initialize(IncrementalGeneratorInitializationContext context)
Expand Down Expand Up @@ -46,13 +44,10 @@ public void Initialize(IncrementalGeneratorInitializationContext context)
_paramlessFlowTypeSymbol = complication.GetTypeByMetadataName(ParamlessFlowType);
_unitFlowTypeSymbol = complication.GetTypeByMetadataName(UnitFlowType);
_resultFlowTypeSymbol = complication.GetTypeByMetadataName(ResultFlowType);
_exposeStateTypeSymbol = complication.GetTypeByMetadataName(IExposeStateType);
if (_exposeStateTypeSymbol != null)
_exposeStateTypeSymbol = _exposeStateTypeSymbol.ConstructUnboundGenericType();
_ignoreAttribute = complication.GetTypeByMetadataName(IgnoreAttribute);
}

if (_paramlessFlowTypeSymbol == null || _unitFlowTypeSymbol == null || _resultFlowTypeSymbol == null || _exposeStateTypeSymbol == null)
if (_paramlessFlowTypeSymbol == null || _unitFlowTypeSymbol == null || _resultFlowTypeSymbol == null)
return null;

var classDeclaration = (ClassDeclarationSyntax) context.TargetNode;
Expand All @@ -75,17 +70,6 @@ public void Initialize(IncrementalGeneratorInitializationContext context)

if (flowType.ContainingType != null || flowType.IsFileLocal)
return null;

ITypeSymbol? stateTypeSymbol = null;
foreach (var implementedInterface in flowType.AllInterfaces)
if (
implementedInterface.IsGenericType &&
SymbolEqualityComparer.Default.Equals(implementedInterface.ConstructUnboundGenericType(), _exposeStateTypeSymbol)
)
{
stateTypeSymbol = implementedInterface.TypeArguments[0];
break;
}

var hasIgnoreAttribute = flowType
.GetAttributes()
Expand All @@ -104,7 +88,6 @@ public void Initialize(IncrementalGeneratorInitializationContext context)
paramType: null,
parameterName: null,
resultType: null,
stateTypeSymbol,
paramless: true,
accessibilityModifier
)
Expand All @@ -126,7 +109,6 @@ public void Initialize(IncrementalGeneratorInitializationContext context)
paramType,
parameterName,
resultType,
stateTypeSymbol,
paramless: false,
accessibilityModifier
)
Expand All @@ -145,9 +127,6 @@ private GeneratedFlowInformation GenerateCode(FlowInformation flowInformation)
var resultType = flowInformation.ResultTypeSymbol != null
? GetFullyQualifiedName(flowInformation.ResultTypeSymbol)
: null;
var stateType = flowInformation.StateTypeSymbol == null
? null
: GetFullyQualifiedName(flowInformation.StateTypeSymbol);

var accessibilityModifier = flowInformation.AccessibilityModifier;

Expand Down Expand Up @@ -197,16 +176,6 @@ private GeneratedFlowInformation GenerateCode(FlowInformation flowInformation)
#nullable disable
}}";
}

if (flowInformation.StateTypeSymbol != null)
{
var getStateStr = $@"
public Task<{stateType}?> GetState(string instanceId)
=> GetState<{stateType}>(instanceId);";
var constructorEndPosition = generatedCode.IndexOf("{ }", StringComparison.Ordinal);
generatedCode = generatedCode.Insert(constructorEndPosition + 3, getStateStr);
}

return new GeneratedFlowInformation(generatedCode, GetFileName(flowInformation));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ public static async Task Main(string[] args)
}

[GenerateFlows]
public class SimpleFlow : Flow, IExposeState<SimpleFlow.FlowState>
public class SimpleFlow : Flow
{
public required FlowState State { get; init; }

Expand Down

0 comments on commit c9ec57c

Please sign in to comment.