From 201102ea8596d22799dccb187f57fd660b57f220 Mon Sep 17 00:00:00 2001 From: Yevhen Bobrov Date: Fri, 22 Nov 2019 00:34:36 +0200 Subject: [PATCH] Align MayInterleave callback signature with 2.x --- Source/Example.EventSourcing.FSM/Domain.cs | 3 +- .../Example.EventSourcing.Idiomatic/Domain.cs | 3 +- .../Domain.cs | 3 +- .../Domain.cs | 3 +- Source/Example.Reentrant/ReaderWriterLock.cs | 3 +- Source/Orleankka.Runtime/ActorAttributes.cs | 17 ++++++----- Source/Orleankka.Runtime/Core/ActorType.cs | 22 ++------------ .../InvokeMethodRequestExtensions.cs | 29 +++++++++++++++++++ .../Features/Reentrant_messages.cs | 7 +++-- 9 files changed, 55 insertions(+), 35 deletions(-) create mode 100644 Source/Orleankka.Runtime/InvokeMethodRequestExtensions.cs diff --git a/Source/Example.EventSourcing.FSM/Domain.cs b/Source/Example.EventSourcing.FSM/Domain.cs index 79b3273c..7d9e92fc 100644 --- a/Source/Example.EventSourcing.FSM/Domain.cs +++ b/Source/Example.EventSourcing.FSM/Domain.cs @@ -4,6 +4,7 @@ using Orleankka.Meta; using Orleankka.Behaviors; +using Orleans.CodeGeneration; using Orleans.Concurrency; namespace Example @@ -14,7 +15,7 @@ public interface IInventoryItem : IActor [MayInterleave(nameof(IsReentrant))] public class InventoryItem : EventSourcedFsmActor, IInventoryItem { - public static bool IsReentrant(object msg) => msg is GetDetails; + public static bool IsReentrant(InvokeMethodRequest req) => req.Message(x => x is GetDetails); string name; int total; diff --git a/Source/Example.EventSourcing.Idiomatic/Domain.cs b/Source/Example.EventSourcing.Idiomatic/Domain.cs index 882442ef..9543d6b2 100644 --- a/Source/Example.EventSourcing.Idiomatic/Domain.cs +++ b/Source/Example.EventSourcing.Idiomatic/Domain.cs @@ -5,6 +5,7 @@ using Orleankka; using Orleankka.Meta; +using Orleans.CodeGeneration; using Orleans.Concurrency; namespace Example @@ -14,7 +15,7 @@ public interface IInventoryItem : IActor {} [MayInterleave(nameof(IsReentrant))] public class InventoryItem : EventSourcedActor, IInventoryItem { - public static bool IsReentrant(object msg) => msg is GetDetails; + public static bool IsReentrant(InvokeMethodRequest req) => req.Message(x => x is GetDetails); int total; string name; diff --git a/Source/Example.EventSourcing.Persistence.GES/Domain.cs b/Source/Example.EventSourcing.Persistence.GES/Domain.cs index 8315e703..4ba088bb 100644 --- a/Source/Example.EventSourcing.Persistence.GES/Domain.cs +++ b/Source/Example.EventSourcing.Persistence.GES/Domain.cs @@ -5,6 +5,7 @@ using Orleankka; using Orleankka.Meta; +using Orleans.CodeGeneration; using Orleans.Concurrency; namespace Example @@ -15,7 +16,7 @@ public interface IInventoryItem : IActor [MayInterleave(nameof(IsReentrant))] public class InventoryItem : EventSourcedActor, IInventoryItem { - public static bool IsReentrant(object msg) => msg is GetDetails; + public static bool IsReentrant(InvokeMethodRequest req) => req.Message(x => x is GetDetails); int total; string name; diff --git a/Source/Example.EventSourcing.Persistence.Streamstone/Domain.cs b/Source/Example.EventSourcing.Persistence.Streamstone/Domain.cs index 76ac7a6a..6ce3d6ad 100644 --- a/Source/Example.EventSourcing.Persistence.Streamstone/Domain.cs +++ b/Source/Example.EventSourcing.Persistence.Streamstone/Domain.cs @@ -4,6 +4,7 @@ using Orleankka; using Orleankka.Meta; +using Orleans.CodeGeneration; using Orleans.Concurrency; namespace Example @@ -14,7 +15,7 @@ public interface IInventoryItem : IActor [MayInterleave(nameof(IsReentrant))] public class InventoryItem : EventSourcedActor, IInventoryItem { - public static bool IsReentrant(object msg) => msg is GetDetails; + public static bool IsReentrant(InvokeMethodRequest req) => req.Message(x => x is GetDetails); int total; string name; diff --git a/Source/Example.Reentrant/ReaderWriterLock.cs b/Source/Example.Reentrant/ReaderWriterLock.cs index cd666ae3..ec5e76de 100644 --- a/Source/Example.Reentrant/ReaderWriterLock.cs +++ b/Source/Example.Reentrant/ReaderWriterLock.cs @@ -5,6 +5,7 @@ using Orleankka; using Orleankka.Meta; +using Orleans.CodeGeneration; using Orleans.Concurrency; namespace Example @@ -26,7 +27,7 @@ public interface IReaderWriterLock : IActor [MayInterleave(nameof(IsReentrant))] public class ReaderWriterLock : Actor, IReaderWriterLock { - public static bool IsReentrant(object msg) => msg is Read; + public static bool IsReentrant(InvokeMethodRequest req) => req.Message(x => x is Read); int value; ConsolePosition indicator; diff --git a/Source/Orleankka.Runtime/ActorAttributes.cs b/Source/Orleankka.Runtime/ActorAttributes.cs index 856ce683..f6498ed2 100644 --- a/Source/Orleankka.Runtime/ActorAttributes.cs +++ b/Source/Orleankka.Runtime/ActorAttributes.cs @@ -4,6 +4,7 @@ using System.Linq.Expressions; using System.Reflection; +using Orleans.CodeGeneration; using Orleans.Internals; using Orleans.Concurrency; @@ -13,7 +14,7 @@ namespace Orleankka class Interleaving { - internal static Func MayInterleavePredicate(Type actor) + internal static Func MayInterleavePredicate(Type actor) { bool reentrant; return MayInterleavePredicate(actor, out reentrant); @@ -26,7 +27,7 @@ internal static bool IsReentrant(Type actor) return reentrant; } - static Func MayInterleavePredicate(Type actor, out bool reentrant) + static Func MayInterleavePredicate(Type actor, out bool reentrant) { reentrant = false; @@ -53,7 +54,7 @@ static Func MayInterleavePredicate(Type actor, out bool reentrant) : null; } - static Func DeterminedByCallbackMethod(Type actor, string callbackMethod) + static Func DeterminedByCallbackMethod(Type actor, string callbackMethod) { var method = actor.GetMethod(callbackMethod, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.FlattenHierarchy); if (method == null) @@ -63,15 +64,15 @@ static Func DeterminedByCallbackMethod(Type actor, string callback if (method.ReturnType != typeof(bool) || method.GetParameters().Length != 1 || - method.GetParameters()[0].ParameterType != typeof(object)) + method.GetParameters()[0].ParameterType != typeof(InvokeMethodRequest)) throw new InvalidOperationException( $"Wrong signature of callback method {callbackMethod} " + - $"specified in Reentrant[] attribute for actor class {actor.FullName}. \n" + - $"Expected: [public] static bool {callbackMethod}(object msg)"); + $"specified in MayInterleave[] attribute for actor class {actor.FullName}. \n" + + $"Expected: [public] static bool {callbackMethod}(InvokeMethodRequest req)"); - var parameter = Expression.Parameter(typeof(object)); + var parameter = Expression.Parameter(typeof(InvokeMethodRequest)); var call = Expression.Call(null, method, parameter); - var predicate = Expression.Lambda>(call, parameter).Compile(); + var predicate = Expression.Lambda>(call, parameter).Compile(); return predicate; } diff --git a/Source/Orleankka.Runtime/Core/ActorType.cs b/Source/Orleankka.Runtime/Core/ActorType.cs index bd2cc02d..aeb6e1b6 100644 --- a/Source/Orleankka.Runtime/Core/ActorType.cs +++ b/Source/Orleankka.Runtime/Core/ActorType.cs @@ -4,12 +4,8 @@ using System.Linq; using System.Reflection; -using Microsoft.Extensions.DependencyInjection; - using Orleans.CodeGeneration; using Orleans.Internals; -using Orleans.Concurrency; -using Orleans.Runtime; namespace Orleankka.Core { @@ -96,7 +92,7 @@ Assembly[] GrainAssemblies(IEnumerable interfaces) => public readonly int TypeCode; internal readonly Type Grain; - readonly Func interleavePredicate; + readonly Func interleavePredicate; readonly string invoker; internal readonly Dispatcher dispatcher; @@ -132,21 +128,7 @@ internal IActorInvoker Invoker(ActorInvocationPipeline pipeline) => /// FOR INTERNAL USE ONLY! /// [UsedImplicitly] - public bool MayInterleave(InvokeMethodRequest request) - { - if (request?.Arguments == null) - return false; - - var receiveMessage = request.Arguments.Length == 1; - if (receiveMessage) - return interleavePredicate(UnwrapImmutable(request.Arguments[0])); - - var streamMessage = request.Arguments.Length == 5; - return streamMessage && interleavePredicate(UnwrapImmutable(request.Arguments[2])); - } - - static object UnwrapImmutable(object item) => - item is Immutable ? ((Immutable)item).Value : item; + public bool MayInterleave(InvokeMethodRequest request) => interleavePredicate(request); internal IEnumerable Subscriptions() => StreamSubscriptionSpecification.From(Class, dispatcher); diff --git a/Source/Orleankka.Runtime/InvokeMethodRequestExtensions.cs b/Source/Orleankka.Runtime/InvokeMethodRequestExtensions.cs new file mode 100644 index 00000000..ba0614ad --- /dev/null +++ b/Source/Orleankka.Runtime/InvokeMethodRequestExtensions.cs @@ -0,0 +1,29 @@ +using System; + +using Orleans.CodeGeneration; +using Orleans.Concurrency; + +namespace Orleankka +{ + public static class InvokeMethodRequestExtensions + { + public static bool Message(this InvokeMethodRequest request, Func predicate) => + predicate(request.Message()); + + public static object Message(this InvokeMethodRequest request) + { + if (request?.Arguments == null) + return null; + + var receiveMessage = request.Arguments.Length == 1; + if (receiveMessage) + return UnwrapImmutable(request.Arguments[0]); + + var streamMessage = request.Arguments.Length == 5; + return streamMessage ? UnwrapImmutable(request.Arguments[2]) : null; + } + + static object UnwrapImmutable(object item) => + item is Immutable immutable ? immutable.Value : item; + } +} \ No newline at end of file diff --git a/Source/Orleankka.Tests/Features/Reentrant_messages.cs b/Source/Orleankka.Tests/Features/Reentrant_messages.cs index bd55a463..3e77695c 100644 --- a/Source/Orleankka.Tests/Features/Reentrant_messages.cs +++ b/Source/Orleankka.Tests/Features/Reentrant_messages.cs @@ -3,6 +3,8 @@ using System.Threading.Tasks; using NUnit.Framework; + +using Orleans.CodeGeneration; using Orleans.Concurrency; namespace Orleankka.Features @@ -39,7 +41,7 @@ interface ITestActor : IActor [MayInterleave(nameof(IsReentrant))] class TestActor : Actor, ITestActor { - public static bool IsReentrant(object msg) => msg is ReentrantMessage; + public static bool IsReentrant(InvokeMethodRequest req) => req.Message(x => x is ReentrantMessage); readonly ActorState state = new ActorState(); @@ -73,7 +75,8 @@ interface ITestReentrantStreamConsumerActor : IActor [MayInterleave(nameof(IsReentrant))] class TestReentrantStreamConsumerActor : Actor, ITestReentrantStreamConsumerActor { - public static bool IsReentrant(object msg) => msg is GetStreamMessagesInProgress || msg is int; + public static bool IsReentrant(InvokeMethodRequest req) => + req.Message(x => x is GetStreamMessagesInProgress || x is int); readonly List streamMessagesInProgress = new List(); List On(GetStreamMessagesInProgress x) => streamMessagesInProgress;