From 8261c688378ac21cb3a1b685b0a8114fbf285484 Mon Sep 17 00:00:00 2001 From: Roger Johansson Date: Mon, 9 May 2022 14:30:05 +0200 Subject: [PATCH 1/4] copy gossip state --- src/Proto.Cluster/Gossip/GossipActor.cs | 2 +- src/Proto.Remote/Endpoints/ServerConnector.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Proto.Cluster/Gossip/GossipActor.cs b/src/Proto.Cluster/Gossip/GossipActor.cs index f70e26bd95..bbf6d474a3 100644 --- a/src/Proto.Cluster/Gossip/GossipActor.cs +++ b/src/Proto.Cluster/Gossip/GossipActor.cs @@ -159,7 +159,7 @@ private void SendGossipForMember(IContext context, Member member, InstanceLogger context.RequestReenter(pid, new GossipRequest { MemberId = context.System.Id, - State = memberStateDelta.State + State = memberStateDelta.State.Clone(), //ensure we have a copy and not send state that might mutate }, task => GossipReenterAfterSend(context, task, memberStateDelta), CancellationTokens.WithTimeout(_gossipRequestTimeout) diff --git a/src/Proto.Remote/Endpoints/ServerConnector.cs b/src/Proto.Remote/Endpoints/ServerConnector.cs index fa8fa351a3..bc6ae2f1ef 100644 --- a/src/Proto.Remote/Endpoints/ServerConnector.cs +++ b/src/Proto.Remote/Endpoints/ServerConnector.cs @@ -166,7 +166,7 @@ await call.RequestStream.WriteAsync(new RemoteMessage var sw = Stopwatch.StartNew(); await call.RequestStream.WriteAsync(message).ConfigureAwait(false); sw.Stop(); - RemoteMetrics.RemoteWriteDuration.Record(sw.ElapsedMilliseconds, _metricTags); + RemoteMetrics.RemoteWriteDuration.Record(sw.Elapsed.TotalSeconds, _metricTags); } else { From d9077a3d4fa1f6b6540a679504938bd21e8ef139 Mon Sep 17 00:00:00 2001 From: Roger Johansson Date: Mon, 9 May 2022 14:30:52 +0200 Subject: [PATCH 2/4] . --- src/Proto.Cluster/Gossip/GossipActor.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Proto.Cluster/Gossip/GossipActor.cs b/src/Proto.Cluster/Gossip/GossipActor.cs index bbf6d474a3..12ffcb43a7 100644 --- a/src/Proto.Cluster/Gossip/GossipActor.cs +++ b/src/Proto.Cluster/Gossip/GossipActor.cs @@ -112,7 +112,7 @@ private Task OnGossipRequest(IContext context, GossipRequest gossipRequest) context.RequestReenter(context.Sender!, new GossipResponse { - State = memberState.State + State = memberState.State.Clone(), //ensure we have a copy and not state that might mutate }, task => ReenterAfterResponseAck(context, task, memberState), context.CancellationToken ); From 15d6c333205d7f777db139164000fb89627a1d66 Mon Sep 17 00:00:00 2001 From: Roger Johansson Date: Tue, 10 May 2022 12:25:17 +0200 Subject: [PATCH 3/4] deadletter logging --- src/Proto.Actor/Configuration/ActorSystemConfig.cs | 3 +++ src/Proto.Actor/Context/BatchContext.cs | 4 ++++ src/Proto.Actor/Context/ISenderContext.cs | 6 ++++++ 3 files changed, 13 insertions(+) diff --git a/src/Proto.Actor/Configuration/ActorSystemConfig.cs b/src/Proto.Actor/Configuration/ActorSystemConfig.cs index 2332d4f5f5..a53b432cc8 100644 --- a/src/Proto.Actor/Configuration/ActorSystemConfig.cs +++ b/src/Proto.Actor/Configuration/ActorSystemConfig.cs @@ -81,6 +81,7 @@ public record ActorSystemConfig /// The default timeout for RequestAsync calls /// public TimeSpan ActorRequestTimeout { get; init; } = TimeSpan.FromSeconds(5); + public bool DeadLetterResponseLogging { get; init; } = false; /// /// Creates a new default ActorSystemConfig @@ -112,6 +113,8 @@ public ActorSystemConfig WithThreadPoolStatsTimeout(TimeSpan threadPoolStatsTime public ActorSystemConfig WithDeveloperThreadPoolStatsLogging(bool enabled) => this with {DeveloperThreadPoolStatsLogging = enabled}; public ActorSystemConfig WithActorRequestTimeout(TimeSpan timeout) => this with {ActorRequestTimeout = timeout}; + + public ActorSystemConfig WithDeadLetterResponseLogging(bool enabled) => this with {DeadLetterResponseLogging = enabled}; } //Not part of the contract, but still shipped out of the box diff --git a/src/Proto.Actor/Context/BatchContext.cs b/src/Proto.Actor/Context/BatchContext.cs index 881641382b..db1767df79 100644 --- a/src/Proto.Actor/Context/BatchContext.cs +++ b/src/Proto.Actor/Context/BatchContext.cs @@ -39,6 +39,10 @@ public async Task RequestAsync(PID target, object message, CancellationTok switch (result) { case DeadLetterResponse: + if (_context.System.Config.DeadLetterResponseLogging) + { + Logger.LogError("BatchContext {Self} got DeadLetterResponse for PID {Pid}", _context.Self , target); + } throw new DeadLetterException(target); case null: case T: diff --git a/src/Proto.Actor/Context/ISenderContext.cs b/src/Proto.Actor/Context/ISenderContext.cs index 383e6c5c28..cf5657aedc 100644 --- a/src/Proto.Actor/Context/ISenderContext.cs +++ b/src/Proto.Actor/Context/ISenderContext.cs @@ -6,6 +6,7 @@ using System; using System.Threading; using System.Threading.Tasks; +using Microsoft.Extensions.Logging; using Proto.Context; using Proto.Future; @@ -58,6 +59,7 @@ public interface ISenderContext : IInfoContext public static class SenderContextExtensions { + private static readonly ILogger Logger = Log.CreateLogger(nameof(SenderContextExtensions)); /// /// Creates a batch context for sending a set of requests from the same thread context. /// This is useful if you have several messages which shares a cancellation scope (same cancellationToken). @@ -173,6 +175,10 @@ internal static async Task RequestAsync(this ISenderContext self, PID targ switch (messageResult) { case DeadLetterResponse: + if (self.System.Config.DeadLetterResponseLogging) + { + Logger.LogError("BatchContext {Self} got DeadLetterResponse for PID {Pid}", self.Self , target); + } throw new DeadLetterException(target); case null: case T: From a166e8980db80fa264dc519414eb1faa3a197f0d Mon Sep 17 00:00:00 2001 From: Roger Johansson Date: Tue, 10 May 2022 12:28:51 +0200 Subject: [PATCH 4/4] . --- src/Proto.Actor/Context/ISenderContext.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Proto.Actor/Context/ISenderContext.cs b/src/Proto.Actor/Context/ISenderContext.cs index cf5657aedc..a8df119cd4 100644 --- a/src/Proto.Actor/Context/ISenderContext.cs +++ b/src/Proto.Actor/Context/ISenderContext.cs @@ -177,7 +177,7 @@ internal static async Task RequestAsync(this ISenderContext self, PID targ case DeadLetterResponse: if (self.System.Config.DeadLetterResponseLogging) { - Logger.LogError("BatchContext {Self} got DeadLetterResponse for PID {Pid}", self.Self , target); + Logger.LogError("Context {Self} got DeadLetterResponse for PID {Pid}", self.Self , target); } throw new DeadLetterException(target); case null: