From a0bf5ddeab14721822bf02af1d5529f2b30c5d98 Mon Sep 17 00:00:00 2001 From: Swen Mun Date: Mon, 24 Aug 2020 22:55:51 +0900 Subject: [PATCH] Add Swarm.LastMessageTimestamp --- CHANGES.md | 2 ++ .../Net/Protocols/TestTransport.cs | 4 +++ Libplanet.Tests/Net/SwarmTest.cs | 29 +++++++++++++++++++ Libplanet/Net/ITransport.cs | 2 ++ Libplanet/Net/NetMQTransport.cs | 3 ++ Libplanet/Net/Swarm.cs | 7 +++-- 6 files changed, 45 insertions(+), 2 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index b65ae52449a..8c503718076 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -144,6 +144,7 @@ To be released. - Added `SwarmOptions` class. [[#926]] - Added `PeerChainState` struct. [[#936]] - Added `Swarm.GetPeerChainStateAsync()` method. [[#936]] + - Added `Swarm.LastMessageTimestamp` property. [[#964]] - Added `Block.EvaluationDigest` property. [[#931], [#935]] - Added `BlockHeader.EvaluationDigest` property. [[#931], [#935]] - Added `Block.PreEvaluationHash` property. [[#931], [#935]] @@ -285,6 +286,7 @@ To be released. [#959]: https://github.com/planetarium/libplanet/issues/959 [#954]: https://github.com/planetarium/libplanet/pull/954 [#963]: https://github.com/planetarium/libplanet/pull/963 +[#964]: https://github.com/planetarium/libplanet/pull/964 [sleep mode]: https://en.wikipedia.org/wiki/Sleep_mode diff --git a/Libplanet.Tests/Net/Protocols/TestTransport.cs b/Libplanet.Tests/Net/Protocols/TestTransport.cs index 1713083a2d2..37f3912afdd 100644 --- a/Libplanet.Tests/Net/Protocols/TestTransport.cs +++ b/Libplanet.Tests/Net/Protocols/TestTransport.cs @@ -80,6 +80,8 @@ internal class TestTransport : ITransport public IEnumerable Peers => Protocol.Peers; + public DateTimeOffset LastMessageTimestamp { get; private set; } + internal ConcurrentBag ReceivedMessages { get; } internal IProtocol Protocol { get; } @@ -341,6 +343,7 @@ public void BroadcastMessage(Address? except, Message message) "Received reply {Reply} of message with identity {identity}.", reply, message.Identity); + LastMessageTimestamp = DateTimeOffset.UtcNow; ReceivedMessages.Add(reply); Protocol.ReceiveMessage(reply); MessageReceived.Set(); @@ -454,6 +457,7 @@ private void ReceiveMessage(Message message) }); } + LastMessageTimestamp = DateTimeOffset.UtcNow; ReceivedMessages.Add(message); Protocol.ReceiveMessage(message); MessageReceived.Set(); diff --git a/Libplanet.Tests/Net/SwarmTest.cs b/Libplanet.Tests/Net/SwarmTest.cs index ecbfaf8dff0..e2bf55857f7 100644 --- a/Libplanet.Tests/Net/SwarmTest.cs +++ b/Libplanet.Tests/Net/SwarmTest.cs @@ -2080,6 +2080,35 @@ public async Task GetPeerChainStateAsync() } } + [Fact(Timeout = Timeout)] + public async Task LastMessageTimestamp() + { + Swarm swarm1 = _swarms[0]; + Swarm swarm2 = _swarms[1]; + + Assert.Null(swarm1.LastMessageTimestamp); + + try + { + await StartAsync(swarm1); + DateTimeOffset bootstrappedAt = DateTimeOffset.UtcNow; + await BootstrapAsync(swarm2, swarm1.AsPeer); + await StartAsync(swarm2); + + Assert.NotNull(swarm1.LastMessageTimestamp); + Assert.InRange( + swarm1.LastMessageTimestamp.Value, + bootstrappedAt, + DateTimeOffset.UtcNow + ); + } + finally + { + await StopAsync(swarm1); + await StopAsync(swarm2); + } + } + private async Task StartAsync( Swarm swarm, IImmutableSet
trustedStateValidators = null, diff --git a/Libplanet/Net/ITransport.cs b/Libplanet/Net/ITransport.cs index 9861f9925db..5696dfb011a 100644 --- a/Libplanet/Net/ITransport.cs +++ b/Libplanet/Net/ITransport.cs @@ -12,6 +12,8 @@ internal interface ITransport : IDisposable IEnumerable Peers { get; } + DateTimeOffset LastMessageTimestamp { get; } + Task StartAsync(CancellationToken cancellationToken = default(CancellationToken)); Task RunAsync(CancellationToken cancellationToken = default(CancellationToken)); diff --git a/Libplanet/Net/NetMQTransport.cs b/Libplanet/Net/NetMQTransport.cs index d9880458d31..28e6013213e 100644 --- a/Libplanet/Net/NetMQTransport.cs +++ b/Libplanet/Net/NetMQTransport.cs @@ -180,6 +180,8 @@ internal class NetMQTransport : ITransport public IEnumerable Peers => Protocol.Peers; + public DateTimeOffset LastMessageTimestamp { get; private set; } + /// /// Whether this instance is running. /// @@ -582,6 +584,7 @@ private void ReceiveMessage(object sender, NetMQSocketEventArgs e) _differentAppProtocolVersionEncountered); _logger.Debug("A message has parsed: {0}, from {1}", message, message.Remote); MessageHistory.Enqueue(message); + LastMessageTimestamp = DateTimeOffset.UtcNow; try { diff --git a/Libplanet/Net/Swarm.cs b/Libplanet/Net/Swarm.cs index 0aa72db7133..4dbd9f1567a 100644 --- a/Libplanet/Net/Swarm.cs +++ b/Libplanet/Net/Swarm.cs @@ -129,7 +129,6 @@ static Swarm() DateTimeOffset now = createdAt.GetValueOrDefault( DateTimeOffset.UtcNow); - LastReceived = now; TxReceived = new AsyncAutoResetEvent(); BlockHeaderReceived = new AsyncAutoResetEvent(); BlockAppended = new AsyncAutoResetEvent(); @@ -182,7 +181,11 @@ static Swarm() public Peer AsPeer => Transport.AsPeer; - public DateTimeOffset LastReceived { get; private set; } + /// + /// The time the message was last received. + /// + public DateTimeOffset? LastMessageTimestamp => + Running ? Transport.LastMessageTimestamp : (DateTimeOffset?)null; public IDictionary LastSeenTimestamps {