59 changed files
LabApps.Actors.Client.gRPC | ||
actors.proto | ||
GrpcClient.cs | ||
LabApps.Actors.Core | ||
ActorAddress.cs | ||
ActorAttribute.cs | ||
ActorBase.cs | ||
ActorFactories.cs | ||
ActorFactory.cs | ||
ActorHelpers.cs | ||
ActorTypeHelper.cs + | ||
CompletionActor.cs | ||
IActorFactories.cs | ||
IActorFactory.cs | ||
IRuntime.cs | ||
RuntimeBase.cs | ||
TimerActor.cs | ||
VoidActor.cs | ||
LabApps.Actors.Core.Tests | ||
ActorAttributeTests.cs | ||
GoodActor.cs | ||
NotAnActor.cs | ||
LabApps.Actors.Events | ||
Generated.Interfaces.g.cs | ||
Generated.MsgPack.g.cs | ||
LabApps.Actors.Runtime.AzureFn | ||
DomainEntityBase.cs | ||
EntityActorRef.cs | ||
EntityRuntime.cs | ||
LabApps.Actors.Runtime.Coyote | ||
ActorRef.cs | ||
LabApps.Actors.Runtime.SelfHosted | ||
ActorQueue.cs | ||
ActorRef.cs | ||
LocalRuntime.cs | ||
LabApps.Actors.Schemas | ||
ActorId.cs | ||
LabApps.Actors.Server.gRPC | ||
actors.proto | ||
ActorService.cs | ||
LabApps.Actors.Tests | ||
ActorFuncTests.cs | ||
CounterActor.cs | ||
DependencyInjectionTests.cs | ||
GreeterActorTests.cs | ||
MultiRuntimeTests.cs | ||
PersistenceTests.cs | ||
PingActor.cs | ||
PongActor.cs | ||
StreamWriterActor.cs | ||
TestActor.cs | ||
TypedActorFuncTests.cs | ||
TypedActorPerfTests.cs | ||
Testing.Benchmarks | ||
DispatcherL0.cs | ||
Testing.DomainA.Actors | ||
TestActor.cs | ||
TestClient.cs | ||
Testing.DomainB.Actors | ||
GreeterActor.cs | ||
TestActor.cs | ||
TestServer.cs | ||
Testing.DomainB.Proxies | ||
GreeterActor.cs | ||
TestServer.cs | ||
Testing2.AzFnServer2 | ||
ActorEntity.cs | ||
EntityActorRef.cs | ||
EntityRuntime.cs | ||
Testing2.AzFnWorker | ||
Program.cs | ||
Testing2.gRPCCli | ||
AzFnClient.cs | ||
Program.cs | ||
Actors.sln | ||
host.json + | ||
actors.proto
/LabApps.Actors.Client.gRPC/actors.proto-1+1/LabApps.Actors.Client.gRPC/actors.proto
Add comment 17
Add comment 18 message EventRequest {
Add comment 19 string uniqueRequestId = 1;
Add comment 20 Minus string actorTypeFullname = 2;
Add comment 20 Plus string actorTypeGuid = 2;
Add comment 21 string actorKey = 3;
Add comment 22 string eventTypeFullname = 4;
Add comment 23 bytes eventBuffer = 5;
GrpcClient.cs
/LabApps.Actors.Client.gRPC/GrpcClient.cs-6+6/LabApps.Actors.Client.gRPC/GrpcClient.cs
Add comment 10 {
Add comment 11 public interface IActorClient : IDisposable
Add comment 12 {
Add comment 13 Minus ValueTask<IActorData> Send(string requestId, IActorData @event, string targetActorTypeFullname, string targetActorKey);
Add comment 14 Minus ValueTask Signal(string requestId, IActorData @event, string targetActorTypeFullname, string targetActorKey);
Add comment 13 Plus ValueTask<IActorData> Send(string requestId, IActorData @event, Guid targetActorTypeGuid, string targetActorKey);
Add comment 14 Plus ValueTask Signal(string requestId, IActorData @event, Guid targetActorTypeGuid, string targetActorKey);
Add comment 15 ValueTask<IActorData> GetReply(string requestId);
Add comment 16 }
Add comment 17 public sealed class GrpcClient : IActorClient
Add comment 44 }
Add comment 45 }
Add comment 46
Add comment 47 Minus public async ValueTask<IActorData> Send(string requestId, IActorData @event, string targetActorTypeFullname, string targetActorKey)
Add comment 47 Plus public async ValueTask<IActorData> Send(string requestId, IActorData @event, Guid targetActorTypeGuid, string targetActorKey)
Add comment 48 {
Add comment 49 var _eventFactory = _factories.GetFactory(@event.GetType().FullName);
Add comment 50 var actorRequest = new EventRequest()
Add comment 51 {
Add comment 52 UniqueRequestId = requestId,
Add comment 53 Minus ActorTypeFullname = targetActorTypeFullname,
Add comment 53 Plus ActorTypeGuid = targetActorTypeGuid.ToString("N"),
Add comment 54 ActorKey = targetActorKey,
Add comment 55 EventTypeFullname = @event.GetType().FullName,
Add comment 56 EventBuffer = ByteString.CopyFrom(_eventFactory.SaveToBuffer(@event).Span),
Add comment 62 return response;
Add comment 63 }
Add comment 64
Add comment 65 Minus public async ValueTask Signal(string requestId, IActorData @event, string targetActorTypeFullname, string targetActorKey)
Add comment 65 Plus public async ValueTask Signal(string requestId, IActorData @event, Guid targetActorTypeGuid, string targetActorKey)
Add comment 66 {
Add comment 67 var _eventFactory = _factories.GetFactory(@event.GetType().FullName);
Add comment 68 var request = new EventRequest()
Add comment 70 UniqueRequestId = requestId,
Add comment 71 EventTypeFullname = @event.GetType().FullName,
Add comment 72 EventBuffer = ByteString.CopyFrom(_eventFactory.SaveToBuffer(@event).Span),
Add comment 73 Minus ActorTypeFullname = targetActorTypeFullname,
Add comment 73 Plus ActorTypeGuid = targetActorTypeGuid.ToString("N"),
Add comment 74 ActorKey = targetActorKey,
Add comment 75 };
Add comment 76 SignalResponse response = await _client.SendOnlyAsync(request);
Add comment 1 #nullable enable
Add comment 2
Add comment 3 Plus using System;
Add comment 3 4
Add comment 4 5 namespace LabApps.Actors.Core
Add comment 5 6 {
Add comment 6 Minus public readonly struct ActorAddress
Add comment 7 Plus public readonly struct ActorAddress : IEquatable<ActorAddress>
Add comment 7 8 {
Add comment 8 Minus public static ActorAddress Create(string typeFullName, string key) => new ActorAddress(typeFullName, key);
Add comment 9 Plus public static ActorAddress Create(Guid typeGuid, string localKey)
Add comment 10 Plus => new ActorAddress(typeGuid, localKey);
Add comment 11 Plus
Add comment 12 Plus //public static ActorAddress Create<TActor>(string localKey) where TActor : IActor
Add comment 13 Plus // => new ActorAddress(ActorTypeHelper.GetActorTypeGuid<TActor>(), localKey);
Add comment 14 Plus
Add comment 15 Plus //public static ActorAddress Create(Type actorType, string localKey)
Add comment 16 Plus // => new ActorAddress(ActorTypeHelper.GetActorTypeGuid(actorType), localKey);
Add comment 17 Plus
Add comment 18 Plus public static ActorAddress Create(string typeGuid, string localKey)
Add comment 19 Plus => new ActorAddress(Guid.Parse(typeGuid), localKey);
Add comment 20 Plus
Add comment 21 Plus public static ActorAddress Create(string value)
Add comment 22 Plus {
Add comment 23 Plus if (value is null) throw new ArgumentNullException(nameof(value));
Add comment 24 Plus string[] parts = value.Split('/');
Add comment 25 Plus if (parts.Length != 2) throw new ArgumentException("Invalid format", nameof(value));
Add comment 26 Plus return new ActorAddress(Guid.Parse(parts[0]), parts[1]);
Add comment 27 Plus }
Add comment 28 Plus
Add comment 29 Plus public readonly Guid TypeGuid;
Add comment 30 Plus public readonly string LocalKey;
Add comment 31 Plus
Add comment 32 Plus private ActorAddress(Guid typeGuid, string localKey) : this()
Add comment 33 Plus {
Add comment 34 Plus if (typeGuid == default) throw new ArgumentNullException(nameof(typeGuid));
Add comment 35 Plus TypeGuid = typeGuid;
Add comment 36 Plus LocalKey = localKey ?? throw new ArgumentNullException(nameof(localKey));
Add comment 37 Plus }
Add comment 9 38
Add comment 10 Minus public static ActorAddress Create<TActor>(string key) where TActor : IActor => new ActorAddress(typeof(TActor).FullName, key);
Add comment 39 Plus public bool IsInvalid() => LocalKey is null || TypeGuid == default;
Add comment 11 40
Add comment 12 Minus // todo redesign to be typename agnostic (metatype hash?)
Add comment 13 Minus public readonly string TypeFullName;
Add comment 14 Minus public readonly string Key;
Add comment 41 Plus public override string ToString() => $"{TypeGuid.ToString("N")}/{LocalKey}";
Add comment 15 42
Add comment 16 Minus private ActorAddress(string typeFullName, string key) : this()
Add comment 43 Plus public bool Equals(ActorAddress other)
Add comment 17 44 {
Add comment 18 Minus TypeFullName = typeFullName ?? throw new System.ArgumentNullException(nameof(typeFullName));
Add comment 19 Minus Key = key ?? throw new System.ArgumentNullException(nameof(key));
Add comment 45 Plus return other.TypeGuid.Equals(this.TypeGuid)
Add comment 46 Plus && string.Equals(other.LocalKey, this.LocalKey, StringComparison.Ordinal);
Add comment 20 47 }
Add comment 21 48
Add comment 22 Minus public bool IsInvalid() => TypeFullName is null || Key is null;
Add comment 49 Plus public override bool Equals(object obj)
Add comment 50 Plus {
Add comment 51 Plus return obj is ActorAddress other && Equals(other);
Add comment 52 Plus }
Add comment 23 53
Add comment 24 Minus public override string ToString() => $"{TypeFullName}/{Key}";
Add comment 54 Plus public override int GetHashCode()
Add comment 55 Plus {
Add comment 56 Plus int hash = this.TypeGuid.GetHashCode();
Add comment 57 Plus hash = (hash * 397) ^ (this.LocalKey?.GetHashCode() ?? 0);
Add comment 58 Plus return hash;
Add comment 59 Plus }
Add comment 25 60 }
Add comment 26 61 }
ActorAttribute.cs
/LabApps.Actors.Core/ActorAttribute.cs+14/LabApps.Actors.Core/ActorAttribute.cs
Add comment 7 [AttributeUsage(AttributeTargets.Class)]
Add comment 8 public class ActorAttribute : Attribute
Add comment 9 {
Add comment 10 Plus private readonly Guid _typeGuid;
Add comment 11 Plus public Guid TypeGuid => _typeGuid;
Add comment 12 Plus
Add comment 13 Plus /// <summary>
Add comment 14 Plus /// Initializes a new instance of the <see cref="ActorAttribute"/> class.
Add comment 15 Plus /// </summary>
Add comment 16 Plus /// <param name="typeGuid">A string containing a unique identifier (GUID) for the actor type.</param>
Add comment 17 Plus /// <exception cref="ArgumentException">Cannot be empty - typeGuid</exception>
Add comment 18 Plus public ActorAttribute(string typeGuid)
Add comment 19 Plus {
Add comment 20 Plus Guid id = Guid.Parse(typeGuid);
Add comment 21 Plus if (id == default) throw new ArgumentException("Cannot be empty", nameof(typeGuid));
Add comment 22 Plus _typeGuid = id;
Add comment 23 Plus }
Add comment 10 24 }
Add comment 11 25 }
Add comment 42
Add comment 43 protected ActorBase(string key, IRuntime runtime)
Add comment 44 {
Add comment 45 Minus _address = ActorAddress.Create(GetType().FullName, key);
Add comment 45 Plus Guid guid = runtime.GetActorTypeGuid(this.GetType());
Add comment 46 Plus _address = ActorAddress.Create(guid, key);
Add comment 46 47 _runtime = runtime;
Add comment 47 48 _ref = _runtime.GetTypedRef<TState>(_address);
Add comment 48 49 _stateFactory = _runtime.DataFactories.GetFactory<TState>(); // todo pass in to save time!
Add comment 168 169 protected void SendEventTo<TActor2>(string? key, IActorData @event) where TActor2 : IActor
Add comment 169 170 {
Add comment 170 171 if (key is null) throw new ArgumentNullException(nameof(key));
Add comment 171 Minus var target = _runtime.GetRef(ActorAddress.Create<TActor2>(key));
Add comment 172 Plus var guid = _runtime.GetActorTypeGuid<TActor2>();
Add comment 173 Plus var target = _runtime.GetRef(ActorAddress.Create(guid, key));
Add comment 172 174 SendEventTo(target, @event);
Add comment 173 175 }
Add comment 174 176
Add comment 176 178
Add comment 177 179 protected IActorRef GetRef<TActor2>(string key) where TActor2 : IActor
Add comment 178 180 {
Add comment 179 Minus return _runtime.GetRef(ActorAddress.Create<TActor2>(key));
Add comment 181 Plus var guid = _runtime.GetActorTypeGuid<TActor2>();
Add comment 182 Plus return _runtime.GetRef(ActorAddress.Create(guid, key));
Add comment 180 183 }
Add comment 181 184
Add comment 182 185 protected ITypedActorRef<TState2> GetTypedRef<TState2>(ActorAddress address)
Add comment 183 186 where TState2 : class
Add comment 184 Minus => _runtime.GetTypedRef<TState2>(address);
Add comment 187 Plus {
Add comment 188 Plus return _runtime.GetTypedRef<TState2>(address);
Add comment 189 Plus }
Add comment 185 190
Add comment 191 Plus protected ITypedActorRef<TState2> GetTypedRef<TState2, TActor2>(string key)
Add comment 192 Plus where TState2 : class
Add comment 193 Plus where TActor2 : IActor
Add comment 194 Plus {
Add comment 195 Plus return _runtime.GetTypedRef<TState2, TActor2>(key);
Add comment 196 Plus }
Add comment 186 197 }
Add comment 187 198 }
ActorFactories.cs
/LabApps.Actors.Core/ActorFactories.cs-7+25/LabApps.Actors.Core/ActorFactories.cs
Add comment 3 using System;
Add comment 4 using System.Collections.Generic;
Add comment 5 using System.Collections.Immutable;
Add comment 6 Plus using System.Diagnostics.CodeAnalysis;
Add comment 6 7 using System.Linq;
Add comment 7 8 using System.Reflection;
Add comment 8 9
Add comment 96 97 }
Add comment 97 98 internal sealed class ActorFactories : IActorFactories
Add comment 98 99 {
Add comment 99 Minus private readonly ImmutableDictionary<string, IActorFactory> _factories = ImmutableDictionary<string, IActorFactory>.Empty;
Add comment 100 Plus private readonly ImmutableDictionary<Guid, IActorFactory> _factories = ImmutableDictionary<Guid, IActorFactory>.Empty;
Add comment 100 101
Add comment 101 102 public ActorFactories(IEnumerable<IActorFactory> factories)
Add comment 102 103 {
Add comment 103 Minus _factories = ImmutableDictionary<string, IActorFactory>.Empty
Add comment 104 Minus .AddRange(factories.Select(f => new KeyValuePair<string, IActorFactory>(f.ActorTypeFullName, f)));
Add comment 104 Plus _factories = ImmutableDictionary<Guid, IActorFactory>.Empty
Add comment 105 Plus .AddRange(factories.Select(f => new KeyValuePair<Guid, IActorFactory>(f.ActorTypeGuid, f)));
Add comment 105 106 }
Add comment 106 107
Add comment 107 108 public IEnumerable<IActorFactory> GetFactories()
Add comment 109 110 return _factories.Values;
Add comment 110 111 }
Add comment 111 112
Add comment 112 Minus public IActorFactory GetFactory(string typeFullName)
Add comment 113 Plus public IActorFactory? TryGetFactory(Guid typeGuid)
Add comment 114 Plus {
Add comment 115 Plus if (_factories.TryGetValue(typeGuid, out var factory))
Add comment 116 Plus return factory;
Add comment 117 Plus else
Add comment 118 Plus return null;
Add comment 119 Plus }
Add comment 120 Plus
Add comment 121 Plus public IActorFactory GetFactory(Guid typeGuid)
Add comment 113 122 {
Add comment 114 Minus if (!_factories.TryGetValue(typeFullName, out var factory))
Add comment 123 Plus if (!_factories.TryGetValue(typeGuid, out var factory))
Add comment 115 124 {
Add comment 116 Minus throw new ArgumentException($"No actor factory found for type '{typeFullName}'", nameof(typeFullName));
Add comment 125 Plus throw new InvalidOperationException($"No actor factory found for type '{typeGuid}'");
Add comment 117 126 }
Add comment 118 127 return factory;
Add comment 119 128 }
Add comment 120 129
Add comment 121 130 public IActorFactory GetFactory<TActor>()
Add comment 122 131 {
Add comment 123 Minus return GetFactory(typeof(TActor).FullName);
Add comment 132 Plus Guid actorTypeGuid = ActorTypeHelper.GetActorTypeGuid<TActor>();
Add comment 133 Plus var factory = TryGetFactory(actorTypeGuid);
Add comment 134 Plus if (factory is null)
Add comment 135 Plus {
Add comment 136 Plus throw new InvalidOperationException($"No actor factory found for type '{typeof(TActor).Name}'");
Add comment 137 Plus }
Add comment 138 Plus else
Add comment 139 Plus {
Add comment 140 Plus return factory;
Add comment 141 Plus }
Add comment 124 142 }
Add comment 125 143
Add comment 126 144 }
ActorTypeHelper.cs
/LabApps.Actors.Core/ActorTypeHelper.cs/LabApps.Actors.Core/ActorTypeHelper.cs
CompletionActor.cs
/LabApps.Actors.Core/CompletionActor.cs/LabApps.Actors.Core/CompletionActor.cs
IActorFactories.cs
/LabApps.Actors.Core/IActorFactories.cs/LabApps.Actors.Core/IActorFactories.cs
ActorAttributeTests.cs
/LabApps.Actors.Core.Tests/ActorAttributeTests.cs/LabApps.Actors.Core.Tests/ActorAttributeTests.cs
Generated.Interfaces.g.cs
/LabApps.Actors.Events/Generated.Interfaces.g.cs/LabApps.Actors.Events/Generated.Interfaces.g.cs
Generated.MsgPack.g.cs
/LabApps.Actors.Events/Generated.MsgPack.g.cs/LabApps.Actors.Events/Generated.MsgPack.g.cs
DomainEntityBase.cs
/LabApps.Actors.Runtime.AzureFn/DomainEntityBase.cs/LabApps.Actors.Runtime.AzureFn/DomainEntityBase.cs
EntityActorRef.cs
/LabApps.Actors.Runtime.AzureFn/EntityActorRef.cs/LabApps.Actors.Runtime.AzureFn/EntityActorRef.cs
EntityRuntime.cs
/LabApps.Actors.Runtime.AzureFn/EntityRuntime.cs/LabApps.Actors.Runtime.AzureFn/EntityRuntime.cs
ActorQueue.cs
/LabApps.Actors.Runtime.SelfHosted/ActorQueue.cs/LabApps.Actors.Runtime.SelfHosted/ActorQueue.cs
ActorRef.cs
/LabApps.Actors.Runtime.SelfHosted/ActorRef.cs/LabApps.Actors.Runtime.SelfHosted/ActorRef.cs
LocalRuntime.cs
/LabApps.Actors.Runtime.SelfHosted/LocalRuntime.cs/LabApps.Actors.Runtime.SelfHosted/LocalRuntime.cs
ActorService.cs
/LabApps.Actors.Server.gRPC/ActorService.cs/LabApps.Actors.Server.gRPC/ActorService.cs
DependencyInjectionTests.cs
/LabApps.Actors.Tests/DependencyInjectionTests.cs/LabApps.Actors.Tests/DependencyInjectionTests.cs
GreeterActorTests.cs
/LabApps.Actors.Tests/GreeterActorTests.cs/LabApps.Actors.Tests/GreeterActorTests.cs
MultiRuntimeTests.cs
/LabApps.Actors.Tests/MultiRuntimeTests.cs/LabApps.Actors.Tests/MultiRuntimeTests.cs
PersistenceTests.cs
/LabApps.Actors.Tests/PersistenceTests.cs/LabApps.Actors.Tests/PersistenceTests.cs
StreamWriterActor.cs
/LabApps.Actors.Tests/StreamWriterActor.cs/LabApps.Actors.Tests/StreamWriterActor.cs
TypedActorFuncTests.cs
/LabApps.Actors.Tests/TypedActorFuncTests.cs/LabApps.Actors.Tests/TypedActorFuncTests.cs
TypedActorPerfTests.cs
/LabApps.Actors.Tests/TypedActorPerfTests.cs/LabApps.Actors.Tests/TypedActorPerfTests.cs