public void DataEnvelope_must_merge_correctly() { var g1 = GCounter.Empty.Increment(node1, 1); var d1 = new DataEnvelope(g1); var g2 = GCounter.Empty.Increment(node2, 2); var d2 = new DataEnvelope(g2); var d3 = d1.Merge(d2); ((GCounter)d3.Data).Value.Should().Be(3); ((GCounter)d3.Data).ModifiedByNodes.Should().BeEquivalentTo(node1, node2); var d4 = d3.InitRemovedNodePruning(node1, node2); var d5 = d4.Prune(node1, new PruningPerformed(obsoleteTimeInFuture)); ((GCounter)d5.Data).ModifiedByNodes.Should().BeEquivalentTo(node2); // late update from node 1 var g11 = g1.Increment(node1, 10); var d6 = d5.Merge(new DataEnvelope(g11)); ((GCounter)d6.Data).Value.Should().Be(3); ((GCounter)d6.Data).ModifiedByNodes.Should().BeEquivalentTo(node2); // remove obsolete var d7 = new DataEnvelope(d5.Data, d5.Pruning.SetItem(node1, new PruningPerformed(obsoleteTime)), d5.DeltaVersions); var d8 = new DataEnvelope(d5.Data, ImmutableDictionary <UniqueAddress, IPruningState> .Empty, d5.DeltaVersions); d8.Merge(d7).Pruning.Should().BeEmpty(); d7.Merge(d8).Pruning.Should().BeEmpty(); d5.Merge(d7).Pruning[node1].Should().Be(new PruningPerformed(obsoleteTimeInFuture)); d7.Merge(d5).Pruning[node1].Should().Be(new PruningPerformed(obsoleteTimeInFuture)); }
protected override bool Receive(object message) => message.Match() .With <ReadResult>(x => { if (x.Envelope != null) { _result = _result?.Merge(x.Envelope) ?? x.Envelope; } Remaining = Remaining.Remove(Sender.Path.Address); var done = DoneWhenRemainingSize; Log.Debug("read acks remaining: {0}, done when: {1}, current state: {2}", Remaining.Count, done, _result); if (Remaining.Count == done) { Reply(true); } }) .With <SendToSecondary>(x => { foreach (var n in SecondaryNodes) { Replica(n).Tell(_read); } }) .With <ReceiveTimeout>(_ => Reply(false)) .WasHandled;
public void DataEnvelope_must_handle_pruning_transitions() { var g1 = GCounter.Empty.Increment(node1, 1); var d1 = new DataEnvelope(g1); var d2 = d1.InitRemovedNodePruning(node1, node2); d2.Pruning[node1].Should().BeOfType <PruningInitialized>(); ((PruningInitialized)d2.Pruning[node1]).Owner.Should().Be(node2); // bug check for https://github.com/akkadotnet/akka.net/issues/4200 var merged = d1.Merge(d2); merged.Data.As <GCounter>().Value.Should().Be(1); var d3 = d2.AddSeen(node3.Address); ((PruningInitialized)d3.Pruning[node1]).Seen.Should().BeEquivalentTo(node3.Address); var d4 = d3.Prune(node1, new PruningPerformed(obsoleteTimeInFuture)); ((GCounter)d4.Data).ModifiedByNodes.Should().BeEquivalentTo(node2); // bug check for https://github.com/akkadotnet/akka.net/issues/4200 var merged2 = d2.Merge(d4); merged2.Data.As <GCounter>().Value.Should().Be(1); merged2.NeedPruningFrom(node1).Should().BeFalse(); merged2.Pruning[node1].Should().BeOfType <PruningPerformed>(); }
protected override bool Receive(object message) => message.Match() .With <ReadResult>(x => { if (_result != null && x.Envelope != null) { _result = _result.Merge(x.Envelope.Data); } else if (_result == null && x.Envelope != null) { _result = x.Envelope; } else if (_result != null && x.Envelope == null) { _result = _result; } else { _result = null; } Remaining = Remaining.Remove(Sender.Path.Address); if (Remaining.Count == DoneWhenRemainingSize) { Reply(true); } }) .With <SendToSecondary>(x => { foreach (var n in PrimaryAndSecondaryNodes.Value.Item2) { Replica(n).Tell(_read); } }) .With <ReceiveTimeout>(_ => Reply(false)) .WasHandled;