From 90e60c688bdb3b95772fdfc77f9e21490e1254c1 Mon Sep 17 00:00:00 2001 From: Gregorius Soedharmo Date: Mon, 30 Dec 2024 21:53:43 +0700 Subject: [PATCH] Improve actor telemetry types (#7439) --- ...oreAPISpec.ApproveCore.DotNet.verified.txt | 11 +++++++++ .../CoreAPISpec.ApproveCore.Net.verified.txt | 11 +++++++++ .../Akka/Actor/ActorCell.FaultHandling.cs | 9 ++++++- src/core/Akka/Actor/ActorTelemetry.cs | 24 ++++++++++++++++--- 4 files changed, 51 insertions(+), 4 deletions(-) diff --git a/src/core/Akka.API.Tests/verify/CoreAPISpec.ApproveCore.DotNet.verified.txt b/src/core/Akka.API.Tests/verify/CoreAPISpec.ApproveCore.DotNet.verified.txt index 797ac2a1bb0..b16d008ad18 100644 --- a/src/core/Akka.API.Tests/verify/CoreAPISpec.ApproveCore.DotNet.verified.txt +++ b/src/core/Akka.API.Tests/verify/CoreAPISpec.ApproveCore.DotNet.verified.txt @@ -94,6 +94,7 @@ namespace Akka.Actor public void CheckReceiveTimeout(bool reschedule = True) { } protected void ClearActor(Akka.Actor.ActorBase actor) { } protected void ClearActorCell() { } + protected virtual Akka.Actor.ActorRestarted CreateActorRestartedEvent(System.Exception cause) { } protected virtual Akka.Actor.ActorStarted CreateActorStartedEvent() { } protected virtual Akka.Actor.ActorStopped CreateActorStoppedEvent() { } protected virtual Akka.Actor.ActorBase CreateNewActorInstance() { } @@ -320,9 +321,12 @@ namespace Akka.Actor public static readonly Akka.Actor.IActorRef NoSender; public static readonly Akka.Actor.Nobody Nobody; } + [System.Runtime.CompilerServices.NullableAttribute(0)] public sealed class ActorRestarted : Akka.Actor.IActorTelemetryEvent, Akka.Actor.INoSerializationVerificationNeeded, Akka.Actor.INotInfluenceReceiveTimeout { + public ActorRestarted(Akka.Actor.IActorRef subject, System.Type actorType, System.Exception reason, [System.Runtime.CompilerServices.NullableAttribute(2)] string actorTypeOverride = null) { } public System.Type ActorType { get; } + public string ActorTypeOverride { get; } public System.Exception Reason { get; } public Akka.Actor.IActorRef Subject { get; } } @@ -352,9 +356,12 @@ namespace Akka.Actor public Akka.Actor.ActorSelectionMessage Copy(object message = null, Akka.Actor.SelectionPathElement[] elements = null, System.Nullable wildCardFanOut = null) { } public override string ToString() { } } + [System.Runtime.CompilerServices.NullableAttribute(0)] public sealed class ActorStarted : Akka.Actor.IActorTelemetryEvent, Akka.Actor.INoSerializationVerificationNeeded, Akka.Actor.INotInfluenceReceiveTimeout { + public ActorStarted(Akka.Actor.IActorRef subject, System.Type actorType, [System.Runtime.CompilerServices.NullableAttribute(2)] string actorTypeOverride = null) { } public System.Type ActorType { get; } + public string ActorTypeOverride { get; } public Akka.Actor.IActorRef Subject { get; } } public class ActorStashPlugin : Akka.Actor.ActorProducerPluginBase @@ -364,9 +371,12 @@ namespace Akka.Actor public override void BeforeIncarnated(Akka.Actor.ActorBase actor, Akka.Actor.IActorContext context) { } public override bool CanBeAppliedTo(System.Type actorType) { } } + [System.Runtime.CompilerServices.NullableAttribute(0)] public sealed class ActorStopped : Akka.Actor.IActorTelemetryEvent, Akka.Actor.INoSerializationVerificationNeeded, Akka.Actor.INotInfluenceReceiveTimeout { + public ActorStopped(Akka.Actor.IActorRef subject, System.Type actorType, [System.Runtime.CompilerServices.NullableAttribute(2)] string actorTypeOverride = null) { } public System.Type ActorType { get; } + public string ActorTypeOverride { get; } public Akka.Actor.IActorRef Subject { get; } } public abstract class ActorSystem : Akka.Actor.IActorRefFactory, System.IDisposable @@ -1025,6 +1035,7 @@ namespace Akka.Actor public interface IActorTelemetryEvent : Akka.Actor.INoSerializationVerificationNeeded, Akka.Actor.INotInfluenceReceiveTimeout { System.Type ActorType { get; } + string ActorTypeOverride { get; } Akka.Actor.IActorRef Subject { get; } } public interface IAdvancedScheduler : Akka.Actor.IActionScheduler, Akka.Actor.IRunnableScheduler { } diff --git a/src/core/Akka.API.Tests/verify/CoreAPISpec.ApproveCore.Net.verified.txt b/src/core/Akka.API.Tests/verify/CoreAPISpec.ApproveCore.Net.verified.txt index a77ae1f67f0..b1c6cb7b794 100644 --- a/src/core/Akka.API.Tests/verify/CoreAPISpec.ApproveCore.Net.verified.txt +++ b/src/core/Akka.API.Tests/verify/CoreAPISpec.ApproveCore.Net.verified.txt @@ -94,6 +94,7 @@ namespace Akka.Actor public void CheckReceiveTimeout(bool reschedule = True) { } protected void ClearActor(Akka.Actor.ActorBase actor) { } protected void ClearActorCell() { } + protected virtual Akka.Actor.ActorRestarted CreateActorRestartedEvent(System.Exception cause) { } protected virtual Akka.Actor.ActorStarted CreateActorStartedEvent() { } protected virtual Akka.Actor.ActorStopped CreateActorStoppedEvent() { } protected virtual Akka.Actor.ActorBase CreateNewActorInstance() { } @@ -320,9 +321,12 @@ namespace Akka.Actor public static readonly Akka.Actor.IActorRef NoSender; public static readonly Akka.Actor.Nobody Nobody; } + [System.Runtime.CompilerServices.NullableAttribute(0)] public sealed class ActorRestarted : Akka.Actor.IActorTelemetryEvent, Akka.Actor.INoSerializationVerificationNeeded, Akka.Actor.INotInfluenceReceiveTimeout { + public ActorRestarted(Akka.Actor.IActorRef subject, System.Type actorType, System.Exception reason, [System.Runtime.CompilerServices.NullableAttribute(2)] string actorTypeOverride = null) { } public System.Type ActorType { get; } + public string ActorTypeOverride { get; } public System.Exception Reason { get; } public Akka.Actor.IActorRef Subject { get; } } @@ -352,9 +356,12 @@ namespace Akka.Actor public Akka.Actor.ActorSelectionMessage Copy(object message = null, Akka.Actor.SelectionPathElement[] elements = null, System.Nullable wildCardFanOut = null) { } public override string ToString() { } } + [System.Runtime.CompilerServices.NullableAttribute(0)] public sealed class ActorStarted : Akka.Actor.IActorTelemetryEvent, Akka.Actor.INoSerializationVerificationNeeded, Akka.Actor.INotInfluenceReceiveTimeout { + public ActorStarted(Akka.Actor.IActorRef subject, System.Type actorType, [System.Runtime.CompilerServices.NullableAttribute(2)] string actorTypeOverride = null) { } public System.Type ActorType { get; } + public string ActorTypeOverride { get; } public Akka.Actor.IActorRef Subject { get; } } public class ActorStashPlugin : Akka.Actor.ActorProducerPluginBase @@ -364,9 +371,12 @@ namespace Akka.Actor public override void BeforeIncarnated(Akka.Actor.ActorBase actor, Akka.Actor.IActorContext context) { } public override bool CanBeAppliedTo(System.Type actorType) { } } + [System.Runtime.CompilerServices.NullableAttribute(0)] public sealed class ActorStopped : Akka.Actor.IActorTelemetryEvent, Akka.Actor.INoSerializationVerificationNeeded, Akka.Actor.INotInfluenceReceiveTimeout { + public ActorStopped(Akka.Actor.IActorRef subject, System.Type actorType, [System.Runtime.CompilerServices.NullableAttribute(2)] string actorTypeOverride = null) { } public System.Type ActorType { get; } + public string ActorTypeOverride { get; } public Akka.Actor.IActorRef Subject { get; } } public abstract class ActorSystem : Akka.Actor.IActorRefFactory, System.IDisposable @@ -1023,6 +1033,7 @@ namespace Akka.Actor public interface IActorTelemetryEvent : Akka.Actor.INoSerializationVerificationNeeded, Akka.Actor.INotInfluenceReceiveTimeout { System.Type ActorType { get; } + string ActorTypeOverride { get; } Akka.Actor.IActorRef Subject { get; } } public interface IAdvancedScheduler : Akka.Actor.IActionScheduler, Akka.Actor.IRunnableScheduler { } diff --git a/src/core/Akka/Actor/ActorCell.FaultHandling.cs b/src/core/Akka/Actor/ActorCell.FaultHandling.cs index f8e98412524..d4afbb0939a 100644 --- a/src/core/Akka/Actor/ActorCell.FaultHandling.cs +++ b/src/core/Akka/Actor/ActorCell.FaultHandling.cs @@ -349,7 +349,7 @@ private void FinishRecreate(Exception cause, ActorBase failedActor) if (System.Settings.DebugLifecycle) Publish(new Debug(_self.Path.ToString(), freshActor.GetType(), "Restarted (" + freshActor + ")")); if(System.Settings.EmitActorTelemetry) - System.EventStream.Publish(new ActorRestarted(Self, Props.Type, cause)); + System.EventStream.Publish(CreateActorRestartedEvent(cause)); // only after parent is up and running again do restart the children which were not stopped foreach (var survivingChild in survivors) @@ -373,6 +373,13 @@ private void FinishRecreate(Exception cause, ActorBase failedActor) } + /// + /// Overrideable in order to support issues such as https://github.com/petabridge/phobos-issues/issues/82 + /// + protected virtual ActorRestarted CreateActorRestartedEvent(Exception cause) + { + return new ActorRestarted(Self, Props.Type, cause); + } private void HandleFailed(Failed f) //Called handleFailure in Akka JVM { diff --git a/src/core/Akka/Actor/ActorTelemetry.cs b/src/core/Akka/Actor/ActorTelemetry.cs index 50437774d07..a4375254e1b 100644 --- a/src/core/Akka/Actor/ActorTelemetry.cs +++ b/src/core/Akka/Actor/ActorTelemetry.cs @@ -8,6 +8,7 @@ using System; using Akka.Event; +#nullable enable namespace Akka.Actor { /// @@ -30,19 +31,28 @@ public interface IActorTelemetryEvent : INoSerializationVerificationNeeded, INot /// The implementation type for this actor. /// Type ActorType { get; } + + /// + /// A type name override for the actor + /// + public string ActorTypeOverride { get; } } // Create ActorTelemetryEvent messages for the following events: starting an actor, stopping an actor, restarting an actor public sealed class ActorStarted : IActorTelemetryEvent { - internal ActorStarted(IActorRef subject, Type actorType) + public ActorStarted(IActorRef subject, Type actorType, string? actorTypeOverride = null) { Subject = subject; ActorType = actorType; + + if(actorTypeOverride is not null) + ActorTypeOverride = actorTypeOverride; } public IActorRef Subject { get; } public Type ActorType { get; } + public string ActorTypeOverride { get; } = string.Empty; } /// @@ -50,14 +60,18 @@ internal ActorStarted(IActorRef subject, Type actorType) /// public sealed class ActorStopped : IActorTelemetryEvent { - internal ActorStopped(IActorRef subject, Type actorType) + public ActorStopped(IActorRef subject, Type actorType, string? actorTypeOverride = null) { Subject = subject; ActorType = actorType; + + if(actorTypeOverride is not null) + ActorTypeOverride = actorTypeOverride; } public IActorRef Subject { get; } public Type ActorType { get; } + public string ActorTypeOverride { get; } = string.Empty; } /// @@ -65,15 +79,19 @@ internal ActorStopped(IActorRef subject, Type actorType) /// public sealed class ActorRestarted : IActorTelemetryEvent { - internal ActorRestarted(IActorRef subject, Type actorType, Exception reason) + public ActorRestarted(IActorRef subject, Type actorType, Exception reason, string? actorTypeOverride = null) { Subject = subject; ActorType = actorType; Reason = reason; + + if(actorTypeOverride is not null) + ActorTypeOverride = actorTypeOverride; } public IActorRef Subject { get; } public Type ActorType { get; } + public string ActorTypeOverride { get; } = string.Empty; public Exception Reason { get; } }