From 11a015e0b66f26a84b943313727ce825170ceb1a Mon Sep 17 00:00:00 2001 From: benbierens Date: Wed, 7 Aug 2024 11:18:40 +0200 Subject: [PATCH] node degree overview --- Framework/Logging/BaseLog.cs | 2 +- Framework/Logging/ConsoleLog.cs | 2 +- Tools/TranscriptAnalysis/Processor.cs | 2 +- Tools/TranscriptAnalysis/Program.cs | 8 +- Tools/TranscriptAnalysis/ReceiverSet.cs | 100 ++++++++++++++++++ .../Receivers/BaseReceiver.cs | 24 +++++ .../DuplicateBlocksReceived.cs | 33 ++---- .../Receivers/LogReplaceReceiver.cs | 28 +++++ .../Receivers/NodesDegree.cs | 51 +++++++++ 9 files changed, 220 insertions(+), 30 deletions(-) create mode 100644 Tools/TranscriptAnalysis/ReceiverSet.cs create mode 100644 Tools/TranscriptAnalysis/Receivers/BaseReceiver.cs rename Tools/TranscriptAnalysis/{ => Receivers}/DuplicateBlocksReceived.cs (73%) create mode 100644 Tools/TranscriptAnalysis/Receivers/LogReplaceReceiver.cs create mode 100644 Tools/TranscriptAnalysis/Receivers/NodesDegree.cs diff --git a/Framework/Logging/BaseLog.cs b/Framework/Logging/BaseLog.cs index cc323a8..afae122 100644 --- a/Framework/Logging/BaseLog.cs +++ b/Framework/Logging/BaseLog.cs @@ -77,7 +77,7 @@ namespace Logging return new LogFile($"{GetFullName()}_{GetSubfileNumber()}", ext); } - private string ApplyReplacements(string str) + protected string ApplyReplacements(string str) { if (IsDebug) return str; foreach (var replacement in replacements) diff --git a/Framework/Logging/ConsoleLog.cs b/Framework/Logging/ConsoleLog.cs index 61da5c8..ab67a40 100644 --- a/Framework/Logging/ConsoleLog.cs +++ b/Framework/Logging/ConsoleLog.cs @@ -9,7 +9,7 @@ public override void Log(string message) { - Console.WriteLine(message); + Console.WriteLine(ApplyReplacements(message)); } } } diff --git a/Tools/TranscriptAnalysis/Processor.cs b/Tools/TranscriptAnalysis/Processor.cs index 8d43739..4d06929 100644 --- a/Tools/TranscriptAnalysis/Processor.cs +++ b/Tools/TranscriptAnalysis/Processor.cs @@ -28,7 +28,7 @@ namespace TranscriptAnalysis if (!reader.Next()) { miss++; - if (miss > 1000) + if (miss > 20) { log.Log("Done"); return; diff --git a/Tools/TranscriptAnalysis/Program.cs b/Tools/TranscriptAnalysis/Program.cs index cc818ec..b1141cb 100644 --- a/Tools/TranscriptAnalysis/Program.cs +++ b/Tools/TranscriptAnalysis/Program.cs @@ -4,11 +4,10 @@ using TranscriptAnalysis; public static class Program { - private static ILog log; + private static readonly ILog log = new ConsoleLog(); public static void Main(string[] args) { - log = new ConsoleLog(); args = new[] { "D:\\Projects\\cs-codex-dist-tests\\Tests\\CodexTests\\bin\\Debug\\net7.0\\CodexTestLogs\\2024-08\\06\\08-24-45Z_ThreeClientTest\\SwarmTest_SwarmTest.owts" }; Log("Transcript Analysis"); @@ -32,12 +31,13 @@ public static class Program CloseReader(reader); }; - var duplicatesReceived = new DuplicateBlocksReceived(log, reader); + var receivers = new ReceiverSet(log, reader); + receivers.InitAll(); var processor = new Processor(log, reader); processor.RunAll(); - duplicatesReceived.Finish(); + receivers.FinishAll(); CloseReader(reader); Log("Done."); diff --git a/Tools/TranscriptAnalysis/ReceiverSet.cs b/Tools/TranscriptAnalysis/ReceiverSet.cs new file mode 100644 index 0000000..036ccda --- /dev/null +++ b/Tools/TranscriptAnalysis/ReceiverSet.cs @@ -0,0 +1,100 @@ +using Logging; +using OverwatchTranscript; +using TranscriptAnalysis.Receivers; + +namespace TranscriptAnalysis +{ + public interface IEventReceiver + { + void Init(ILog log); + void Finish(); + } + + public interface IEventReceiver : IEventReceiver + { + void Receive(ActivateEvent @event); + } + + public class ReceiverSet + { + private readonly ILog log; + private readonly ITranscriptReader reader; + private readonly List receivers = new List(); + + public ReceiverSet(ILog log, ITranscriptReader reader) + { + this.log = log; + this.reader = reader; + } + + public void InitAll() + { + Add(new LogReplaceReceiver()); + Add(new DuplicateBlocksReceived()); + Add(new NodesDegree()); + } + + public void FinishAll() + { + foreach (var r in receivers) + { + r.Finish(); + } + receivers.Clear(); + } + + + private void Add(IEventReceiver receiver) + { + var mux = GetMux(); + mux.Add(receiver); + + receivers.Add(receiver); + receiver.Init(log); + } + + // We use a mux here because, for each time we call reader.AddEventHandler, + // The reader will perform one separate round of JSON deserialization. + // TODO: Move the mux into the reader. + private readonly Dictionary muxes = new Dictionary(); + private IEventMux GetMux() + { + var typeName = typeof(T).FullName; + if (string.IsNullOrEmpty(typeName)) throw new Exception("A!"); + + if (!muxes.ContainsKey(typeName)) + { + muxes.Add(typeName, new EventMux(reader)); + } + return muxes[typeName]; + } + } + + public interface IEventMux + { + void Add(IEventReceiver receiver); + } + + public class EventMux : IEventMux + { + private readonly List> receivers = new List>(); + + public EventMux(ITranscriptReader reader) + { + reader.AddEventHandler(Handle); + } + + public void Add(IEventReceiver receiver) + { + if (receiver is IEventReceiver r) + { + receivers.Add(r); + } + } + + public void Handle(ActivateEvent @event) + { + foreach (var r in receivers) r.Receive(@event); + } + } +} diff --git a/Tools/TranscriptAnalysis/Receivers/BaseReceiver.cs b/Tools/TranscriptAnalysis/Receivers/BaseReceiver.cs new file mode 100644 index 0000000..5a0e4ba --- /dev/null +++ b/Tools/TranscriptAnalysis/Receivers/BaseReceiver.cs @@ -0,0 +1,24 @@ +using Logging; +using OverwatchTranscript; + +namespace TranscriptAnalysis.Receivers +{ + public abstract class BaseReceiver : IEventReceiver + { + protected ILog log { get; private set; } = new NullLog(); + + public abstract string Name { get; } + public abstract void Receive(ActivateEvent @event); + public abstract void Finish(); + + public void Init(ILog log) + { + this.log = new LogPrefixer(log, $"({Name}) "); + } + + protected void Log(string msg) + { + log.Log(msg); + } + } +} diff --git a/Tools/TranscriptAnalysis/DuplicateBlocksReceived.cs b/Tools/TranscriptAnalysis/Receivers/DuplicateBlocksReceived.cs similarity index 73% rename from Tools/TranscriptAnalysis/DuplicateBlocksReceived.cs rename to Tools/TranscriptAnalysis/Receivers/DuplicateBlocksReceived.cs index 3259f48..4a7fa8c 100644 --- a/Tools/TranscriptAnalysis/DuplicateBlocksReceived.cs +++ b/Tools/TranscriptAnalysis/Receivers/DuplicateBlocksReceived.cs @@ -1,21 +1,21 @@ using CodexPlugin.OverwatchSupport; -using Logging; using OverwatchTranscript; -namespace TranscriptAnalysis +namespace TranscriptAnalysis.Receivers { - public class DuplicateBlocksReceived + public class DuplicateBlocksReceived : BaseReceiver { - private readonly ILog log; + public override string Name => "BlocksReceived"; - public DuplicateBlocksReceived(ILog log, ITranscriptReader reader) + public override void Receive(ActivateEvent @event) { - this.log = new LogPrefixer(log, "(DuplicateBlocks) "); - - reader.AddEventHandler(Handle); + if (@event.Payload.BlockReceived != null) + { + Handle(@event.Payload, @event.Payload.BlockReceived); + } } - public void Finish() + public override void Finish() { Log("Number of BlockReceived events seen: " + seen); @@ -28,7 +28,7 @@ namespace TranscriptAnalysis foreach (var pair in peerPair.Value) { occurances[pair.Value]++; - } + } } float t = totalReceived; @@ -40,14 +40,6 @@ namespace TranscriptAnalysis } } - private void Handle(ActivateEvent obj) - { - if (obj.Payload.BlockReceived != null) - { - Handle(obj.Payload, obj.Payload.BlockReceived); - } - } - private int seen = 0; private readonly Dictionary> peerIdBlockAddrCount = new Dictionary>(); @@ -71,10 +63,5 @@ namespace TranscriptAnalysis blockAddCount[blockAddress]++; } } - - private void Log(string v) - { - log.Log(v); - } } } diff --git a/Tools/TranscriptAnalysis/Receivers/LogReplaceReceiver.cs b/Tools/TranscriptAnalysis/Receivers/LogReplaceReceiver.cs new file mode 100644 index 0000000..7a659c6 --- /dev/null +++ b/Tools/TranscriptAnalysis/Receivers/LogReplaceReceiver.cs @@ -0,0 +1,28 @@ +using CodexPlugin; +using CodexPlugin.OverwatchSupport; +using OverwatchTranscript; + +namespace TranscriptAnalysis.Receivers +{ + public class LogReplaceReceiver : BaseReceiver + { + public override string Name => "LogReplacer"; + + private readonly List seen = new List(); + + public override void Receive(ActivateEvent @event) + { + if (!seen.Contains(@event.Payload.PeerId)) + { + seen.Add(@event.Payload.PeerId); + + log.AddStringReplace(@event.Payload.PeerId, @event.Payload.Name); + log.AddStringReplace(CodexUtils.ToShortId(@event.Payload.PeerId), @event.Payload.Name); + } + } + + public override void Finish() + { + } + } +} diff --git a/Tools/TranscriptAnalysis/Receivers/NodesDegree.cs b/Tools/TranscriptAnalysis/Receivers/NodesDegree.cs new file mode 100644 index 0000000..6b57dd8 --- /dev/null +++ b/Tools/TranscriptAnalysis/Receivers/NodesDegree.cs @@ -0,0 +1,51 @@ +using CodexPlugin; +using CodexPlugin.OverwatchSupport; +using OverwatchTranscript; + +namespace TranscriptAnalysis.Receivers +{ + public class NodesDegree : BaseReceiver + { + private readonly Dictionary> dials = new Dictionary>(); + + public override string Name => "NodesDegree"; + + public override void Receive(ActivateEvent @event) + { + if (@event.Payload.DialSuccessful != null) + { + AddDial(@event.Payload.PeerId, @event.Payload.DialSuccessful.TargetPeerId); + } + } + + private void AddDial(string peerId, string targetPeerId) + { + if (!dials.ContainsKey(peerId)) + { + dials.Add(peerId, new Dictionary()); + } + + var d = dials[peerId]; + if (!d.ContainsKey(targetPeerId)) + { + d.Add(targetPeerId, 1); + } + else + { + d[targetPeerId]++; + } + } + + public override void Finish() + { + var numNodes = dials.Keys.Count; + var redials = dials.Values.Count(t => t.Values.Any(nd => nd > 1)); + + var min = dials.Values.Min(t => t.Count); + var avg = dials.Values.Average(t => t.Count); + var max = dials.Values.Max(t => t.Count); + + Log($"Nodes: {numNodes} - Degrees: min:{min} avg:{avg} max:{max} - Redials: {redials}"); + } + } +}