Skip to content

Commit

Permalink
Feat/initialization reworked (#30)
Browse files Browse the repository at this point in the history
* WiP

* Progress ;-)

* Activity: fix for token stream clearing delay

* Release 0.13.2-alpha
  • Loading branch information
mikolaj-milewski authored Aug 3, 2024
1 parent 8602b71 commit 570f82a
Show file tree
Hide file tree
Showing 569 changed files with 12,014 additions and 6,861 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ public ActivityLocator(IBehaviorLocator locator)
Locator = locator;
}

public bool TryLocateActivity(ActivityId id, out IActivity activity)
public bool TryLocateActivity(ActivityId id, out IActivityBehavior activity)
=> Locator.TryLocateActivity(id, out activity);
}
}
18 changes: 9 additions & 9 deletions Core/Stateflows.Common/Activities/Classes/ActivityWrapper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,11 @@
using System.Collections.Generic;
using Stateflows.Activities;
using Stateflows.Activities.Events;
using System.Linq;

namespace Stateflows.Common.Activities.Classes
{
internal class ActivityWrapper : IActivity
internal class ActivityWrapper : IActivityBehavior
{
BehaviorId IBehavior.Id => Behavior.Id;

Expand All @@ -17,16 +18,15 @@ public ActivityWrapper(IBehavior consumer)
Behavior = consumer;
}

public Task<RequestResult<ExecutionResponse>> ExecuteAsync(InitializationRequest initializationRequest = null, IEnumerable<object> inputTokens = null)
{
var executionRequest = new ExecutionRequest(initializationRequest ?? new InitializationRequest(), inputTokens ?? new object[0]);
if (initializationRequest != null)
public Task<RequestResult<ExecutionResponse>> ExecuteAsync(Event initializationEvent, IEnumerable<object> inputTokens = null)
=> Behavior.RequestAsync(new ExecutionRequest()
{
executionRequest.Headers.AddRange(initializationRequest.Headers);
}
InitializationEvent = initializationEvent,
InputTokens = inputTokens ?? new object[0],
});

return Behavior.RequestAsync(executionRequest);
}
public Task<RequestResult<ExecutionResponse>> ExecuteAsync(IEnumerable<object> inputTokens = null)
=> Behavior.RequestAsync(new ExecutionRequest() { InputTokens = inputTokens ?? new object[0] });

public Task<SendResult> SendAsync<TEvent>(TEvent @event)
where TEvent : Event, new()
Expand Down
8 changes: 1 addition & 7 deletions Core/Stateflows.Common/Activities/Events/ExecutionRequest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,7 @@ namespace Stateflows.Activities.Events
{
public sealed class ExecutionRequest : Request<ExecutionResponse>
{
public ExecutionRequest(InitializationRequest initializationRequest, IEnumerable<object> inputTokens)
{
InitializationRequest = initializationRequest;
InputTokens = inputTokens;
}

public InitializationRequest InitializationRequest { get; set; }
public Event InitializationEvent { get; set; } = new Initialize();

[JsonProperty(TypeNameHandling = TypeNameHandling.None)]
public IEnumerable<object> InputTokens { get; set; }
Expand Down
2 changes: 0 additions & 2 deletions Core/Stateflows.Common/Activities/Events/ExecutionResponse.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,6 @@ namespace Stateflows.Activities.Events
{
public sealed class ExecutionResponse : Response
{
public bool ExecutionSuccessful { get; set; }

[JsonProperty(TypeNameHandling = TypeNameHandling.None)]
public IEnumerable<object> OutputTokens { get; set; } = new List<object>();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,18 @@ namespace Stateflows.Activities
{
public static class ExecutionResponseExtensions
{
public static IEnumerable<T> GetOutputValues<T>(this ExecutionResponse response)
public static IEnumerable<T> GetOutputTokensOfType<T>(this ExecutionResponse response)
=> response != null
? response.OutputTokens.OfType<T>().ToArray()
? response.OutputTokens.OfType<TokenHolder<T>>().Select(t => t.Payload).ToArray()
: new T[0];

public static T GetOutputValueOrDefault<T>(this ExecutionResponse response, T defaultValue = default)
public static bool TryGetOutputTokenOfType<T>(this ExecutionResponse response, out T token)
{
var valueTokens = response.GetOutputValues<T>();
var valueTokens = response.GetOutputTokensOfType<T>();

return valueTokens.Any()
? valueTokens.First()
: defaultValue;
token = valueTokens.FirstOrDefault();

return valueTokens.Any();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ namespace Stateflows.Activities
{
public static class IBehaviorLocatorActivityExtensions
{
public static bool TryLocateActivity(this IBehaviorLocator locator, ActivityId id, out IActivity activity)
public static bool TryLocateActivity(this IBehaviorLocator locator, ActivityId id, out IActivityBehavior activity)
=> (
activity = locator.TryLocateBehavior(id.BehaviorId, out var behavior)
? new ActivityWrapper(behavior)
Expand Down
12 changes: 0 additions & 12 deletions Core/Stateflows.Common/Activities/Interfaces/IActivity.cs

This file was deleted.

13 changes: 13 additions & 0 deletions Core/Stateflows.Common/Activities/Interfaces/IActivityBehavior.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
using System.Threading.Tasks;
using System.Collections.Generic;
using Stateflows.Common;
using Stateflows.Activities.Events;

namespace Stateflows.Activities
{
public interface IActivityBehavior : IBehavior
{
Task<RequestResult<ExecutionResponse>> ExecuteAsync(Event initializationEvent, IEnumerable<object> inputTokens = null);
Task<RequestResult<ExecutionResponse>> ExecuteAsync(IEnumerable<object> inputTokens = null);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,6 @@ public interface IActivityLocator
{
IBehaviorLocator Locator { get; }

bool TryLocateActivity(ActivityId id, out IActivity activity);
bool TryLocateActivity(ActivityId id, out IActivityBehavior activity);
}
}
8 changes: 8 additions & 0 deletions Core/Stateflows.Common/Attributes/NoImplicitInitialization.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
using System;

namespace Stateflows.Common
{
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false)]
public sealed class NoImplicitInitializationAttribute : Attribute
{ }
}
2 changes: 1 addition & 1 deletion Core/Stateflows.Common/Classes/SendResult.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
using Newtonsoft.Json;
using System.ComponentModel.DataAnnotations;
using System;
using System.ComponentModel.DataAnnotations;

namespace Stateflows.Common
{
Expand Down
25 changes: 25 additions & 0 deletions Core/Stateflows.Common/Context/StateflowsContext.cs
Original file line number Diff line number Diff line change
@@ -1,26 +1,51 @@
using System;
using System.Linq;
using System.Collections.Generic;
using Newtonsoft.Json;

namespace Stateflows.Common.Context
{
public class StateflowsContext
{
public StateflowsContext()
{
Stored = true;
}

public StateflowsContext(BehaviorId id)
{
Id = id;
Stored = false;
}

public BehaviorId Id { get; set; }

public int Version { get; set; } = 0;

[JsonIgnore]
public bool Deleted { get; set; }

[JsonIgnore]
public bool Stored { get; set; }

public BehaviorStatus Status { get; set; } = BehaviorStatus.Unknown;

public DateTime LastExecutedAt { get; set; }

public DateTime? TriggerTime { get; set; }

public bool TriggerOnStartup { get; set; }

public bool ShouldSerializePendingTimeEvents()
=> PendingTimeEvents.Any();

public Dictionary<Guid, TimeEvent> PendingTimeEvents { get; set; } = new Dictionary<Guid, TimeEvent>();

public bool ShouldSerializePendingStartupEvents()
=> PendingStartupEvents.Any();

public Dictionary<Guid, Startup> PendingStartupEvents { get; set; } = new Dictionary<Guid, Startup>();

public Dictionary<BehaviorId, List<string>> Subscriptions { get; set; } = new Dictionary<BehaviorId, List<string>>();

public bool AddSubscription(BehaviorId subscribeeBehaviorId, string eventName)
Expand Down
13 changes: 0 additions & 13 deletions Core/Stateflows.Common/DependencyInjection.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
using System;
using Microsoft.Extensions.DependencyInjection;
using Stateflows.System;
using Stateflows.Activities;
using Stateflows.StateMachines;
using Stateflows.Common;
Expand All @@ -9,7 +8,6 @@
using Stateflows.Common.Interfaces;
using Stateflows.Common.Extensions;
using Stateflows.Common.Exceptions;
using Stateflows.Common.System.Classes;
using Stateflows.Common.Activities.Classes;
using Stateflows.Common.StateMachines.Classes;
using Stateflows.Common.Registration.Builders;
Expand All @@ -34,17 +32,6 @@ public static IServiceCollection AddStateflowsClient(this IServiceCollection ser
.AddScoped<IBehaviorLocator, BehaviorLocator>()
.AddScoped<IStateMachineLocator, StateMachineLocator>()
.AddScoped<IActivityLocator, ActivityLocator>()
.AddScoped<ISystem>((IServiceProvider provider) =>
{
if (provider.GetRequiredService<IBehaviorLocator>().TryLocateBehavior(SystemBehavior.Id, out var behavior))
{
return new SystemWrapper(behavior);
}
else
{
throw new StateflowsException("System behavior could not be found");
}
})
.AddSingleton<IBehaviorClassesProvider, BehaviorClassesProvider>()
;

Expand Down
22 changes: 17 additions & 5 deletions Core/Stateflows.Common/Enums/EventStatus.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,15 @@
public enum EventStatus
{
/// <summary>
/// Target behavior not found
/// Event has initialized behavior instance
/// </summary>
Initialized,
/// <summary>
/// Event has failed to initialize behavior instance
/// </summary>
NotInitialized,
/// <summary>
/// Event has executed behavior instance
/// </summary>
Undelivered,
/// <summary>
Expand All @@ -15,10 +23,6 @@ public enum EventStatus
/// </summary>
Invalid,
/// <summary>
/// Event was not consumed by behavior
/// </summary>
NotConsumed,
/// <summary>
/// Event was deferred by behavior and can be consumed later
/// </summary>
Deferred,
Expand All @@ -27,10 +31,18 @@ public enum EventStatus
/// </summary>
Consumed,
/// <summary>
/// Event was not consumed by behavior
/// </summary>
NotConsumed,
/// <summary>
/// Event was omitted because other events in CompoundRequest were invalid
/// </summary>
Omitted,
/// <summary>
/// Event caused unhandled exception in behavior
/// </summary>
Failed,
/// <summary>
/// Event was forwarded to embedded behavior
/// </summary>
Forwarded
Expand Down
9 changes: 9 additions & 0 deletions Core/Stateflows.Common/Enums/ExceptionPropagationMode.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
namespace Stateflows.Common
{
public enum ExceptionPropagationMode
{
NoPropagation,
PropagateUnhandled,
PropagateAll
}
}
10 changes: 10 additions & 0 deletions Core/Stateflows.Common/Enums/InitializationStatus.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
namespace Stateflows.Common
{
public enum InitializationStatus
{
InitializedExplicitly,
InitializedImplicitly,
NotInitialized,
NoSuitableInitializer
}
}
9 changes: 9 additions & 0 deletions Core/Stateflows.Common/Enums/ResetMode.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
namespace Stateflows.Common
{
public enum ResetMode
{
KeepVersionAndSubscriptions,
KeepSubscriptions,
Full
}
}
18 changes: 9 additions & 9 deletions Core/Stateflows.Common/Events/Event.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,15 @@ public class Event
public virtual string Name => GetType().GetEventName();
}

public class Event<TPayload> : Event
{
public Event()
{
Payload = default;
}

public TPayload Payload { get; set; }
}
//public class Event<TPayload> : Event
//{
// public Event()
// {
// Payload = default;
// }

// public TPayload Payload { get; set; }
//}

public static class EventInfo<TEvent>
where TEvent : Event, new()
Expand Down
1 change: 1 addition & 0 deletions Core/Stateflows.Common/Events/FinalizationRequest.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
namespace Stateflows.Common
{
[NoImplicitInitialization]
public sealed class FinalizationRequest : Request<FinalizationResponse>
{ }
}
20 changes: 10 additions & 10 deletions Core/Stateflows.Common/Events/InitializationRequest.cs
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
namespace Stateflows.Common
{
public class InitializationRequest : Request<InitializationResponse>
{ }
//public class InitializationRequest : Request<InitializationResponse>
//{ }

public sealed class InitializationRequest<TPayload> : InitializationRequest
{
public InitializationRequest()
{
Payload = default;
}
//public sealed class InitializationRequest<TPayload> : InitializationRequest
//{
// public InitializationRequest()
// {
// Payload = default;
// }

public TPayload Payload { get; set; }
}
// public TPayload Payload { get; set; }
//}
}
8 changes: 4 additions & 4 deletions Core/Stateflows.Common/Events/InitializationResponse.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
namespace Stateflows.Common
{
public sealed class InitializationResponse : Response
{
public bool InitializationSuccessful { get; set; }
}
//public sealed class InitializationResponse : Response
//{
// public bool InitializationSuccessful { get; set; }
//}
}
Loading

0 comments on commit 570f82a

Please sign in to comment.