public void Insert_from_5_nodes_should_read_write_to_majority_when_all_nodes_connected()
        {
            var key           = new ORSetKey <int>("B");
            var readMajority  = new ReadMajority(_timeout);
            var writeMajority = new WriteMajority(_timeout);

            RunOn(() =>
            {
                var writeProbe = CreateTestProbe();
                var writeAcks  = MyData.Select(i =>
                {
                    SleepDelay();
                    _replicator.Tell(Dsl.Update(key, ORSet <int> .Empty, writeMajority, i, x => x.Add(_cluster.SelfUniqueAddress, i)), writeProbe.Ref);
                    return(writeProbe.ReceiveOne(_timeout.Add(TimeSpan.FromSeconds(1))));
                }).ToArray();
                var successWriteAcks = writeAcks.OfType <Replicator.UpdateSuccess>().ToArray();
                var failureWriteAcks = writeAcks.OfType <Replicator.IUpdateFailure>().ToArray();
                successWriteAcks.Select(x => (int)x.Request).ShouldBe(MyData.ToArray());
                successWriteAcks.Length.ShouldBe(MyData.Count());
                failureWriteAcks.ShouldBe(new Replicator.IUpdateFailure[0]);
                (successWriteAcks.Length + failureWriteAcks.Length).ShouldBe(MyData.Count());

                EnterBarrier("data-written-2");

                // read from majority of nodes, which is enough to retrieve all data
                var readProbe = CreateTestProbe();
                _replicator.Tell(Dsl.Get(key, readMajority), readProbe.Ref);
                var result = readProbe.ExpectMsg <Replicator.GetSuccess>(g => Equals(g.Key, key)).Get(key);
                result.Elements.ShouldBe(_expectedData);
            }, _nodes.ToArray());

            RunOn(() => EnterBarrier("data-written-2"), Controller);

            EnterBarrier("after-test-2");
        }
        //The way our data works, I opted to just removed all the key data, but leave the key intact as sometimes i need to use the key again in rare instances, but once deleted, ddata doesn't allow this.
        private void HandleMessage(CloseEvent message)
        {
            try
            {
                var replicator       = DistributedData.Get(Context.System).Replicator;
                var cluster          = Cluster.Get(Context.System);
                var key              = new ORSetKey <string>($"Event-{message.EventId}");
                var writeConsistency = WriteLocal.Instance;
                replicator.Tell(Dsl.Update(key, ORSet <string> .Empty, writeConsistency, $"Event-{message.EventId}",
                                           existing =>
                {
                    return(existing.Clear(cluster));
                }));

                var finalResult =
                    replicator.Ask <IGetResponse>(Dsl.Get(key, ReadLocal.Instance));
                Sender.Tell(finalResult.Result);
            }
            catch (DataDeletedException e)
            {
                Sender.Tell($"Event {message.EventId} has been deleted");
            }
            catch (Exception e)
            {
                _log.Error(e, "Unable to process message CloseEvent for Event {0}", message.EventId);
                Sender.Tell($"Unable to process message CloseEvent for Event {message.EventId}");
            }
        }
Example #3
0
 private void GetState()
 {
     for (int i = 0; i < NrOfKeys; i++)
     {
         Replicator.Tell(Dsl.Get(_stateKeys[i], _readConsistency, i));
     }
 }
Example #4
0
        public void Cluster_CRDT_should_replicate_values_to_new_node()
        {
            Join(_second, _first);

            RunOn(() =>
                  Within(TimeSpan.FromSeconds(10), () =>
                         AwaitAssert(() =>
            {
                _replicator.Tell(Dsl.GetReplicaCount);
                ExpectMsg(new ReplicaCount(2));
            })),
                  _first, _second);

            EnterBarrier("2-nodes");

            RunOn(() =>
            {
                var changedProbe = CreateTestProbe();
                _replicator.Tell(Dsl.Subscribe(KeyA, changedProbe.Ref));
                // "A" should be replicated via gossip to the new node
                Within(TimeSpan.FromSeconds(5), () =>
                       AwaitAssert(() =>
                {
                    //TODO: received message is NotFound(A) instead of GetSuccess
                    // for some reason result is returned before CRDT gets replicated
                    _replicator.Tell(Dsl.Get(KeyA, ReadLocal.Instance));
                    var c = ExpectMsg <GetSuccess>(g => Equals(g.Key, KeyA)).Get(KeyA);
                    c.Value.ShouldBe(6);
                }));
                var c2 = changedProbe.ExpectMsg <Changed>(g => Equals(g.Key, KeyA)).Get(KeyA);
                c2.Value.ShouldBe(6);
            }, _second);

            EnterBarrierAfterTestStep();
        }
Example #5
0
        public void Cluster_CRDT_should_converge_after_many_concurrent_updates()
        {
            Within(TimeSpan.FromSeconds(10), () =>
            {
                RunOn(() =>
                {
                    var c = GCounter.Empty;
                    for (int i = 0; i < 100; i++)
                    {
                        c = c.Increment(_cluster, i);
                        _replicator.Tell(Dsl.Update(KeyF, GCounter.Empty, _writeTwo, x => x.Increment(_cluster, 1)));
                    }

                    var results = ReceiveN(100);
                    results.All(x => x is UpdateSuccess).ShouldBeTrue();
                }, _first, _second, _third);

                EnterBarrier("100-updates-done");

                RunOn(() =>
                {
                    _replicator.Tell(Dsl.Get(KeyF, _readTwo));
                    var c = ExpectMsg <GetSuccess>(g => Equals(g.Key, KeyF)).Get(KeyF);
                    c.Value.ShouldBe(3 * 100);
                }, _first, _second, _third);

                EnterBarrierAfterTestStep();
            });
        }
        private void HandleMessage(CreateEventMarket message)
        {
            try
            {
                var cluster    = Cluster.Get(Context.System);
                var replicator = DistributedData.Get(Context.System).Replicator;

                var key = new ORSetKey <string>($"Event-{message.EventId}");

                var writeConsistency = new WriteMajority(TimeSpan.FromSeconds(2));

                replicator.Tell(Dsl.Update(key, ORSet <string> .Empty, writeConsistency,
                                           existing => existing.Add(cluster, message.Market)));

                var localEvent =
                    replicator.Ask <IGetResponse>(Dsl.Get(key, ReadLocal.Instance));


                Sender.Tell(localEvent.Result);
            }
            catch (Exception e)
            {
                _log.Error(e, "Unable to process message CreateEventMarket for Event {0} Market {1}", message.EventId,
                           message.Market);
                Sender.Tell(
                    $"Unable to process message CreateEventMarket for Event {message.EventId} Market {message.Market}");
            }
        }
        public void Updates_from_same_node_should_be_possible_to_do_from_two_actors()
        {
            var updater1 = ActorOf(Props.Create <Updater>(), "updater1");
            var updater2 = ActorOf(Props.Create <Updater>(), "updater2");

            var b = ImmutableHashSet <string> .Empty.ToBuilder();

            for (int i = 1; i <= 100; i++)
            {
                var m1 = "a" + 1;
                var m2 = "b" + 1;
                updater1.Tell(m1);
                updater2.Tell(m2);

                b.Add(m1);
                b.Add(m2);
            }

            var expected = b.ToImmutable();

            AwaitAssert(() =>
            {
                _replicator.Tell(Dsl.Get(Updater.Key, ReadLocal.Instance));
                var msg      = ExpectMsg <GetSuccess>();
                var elements = msg.Get(Updater.Key).Elements;
                Assert.Equal(expected, elements);
            });
        }
        private void AssertValue(IKey <IReplicatedData> key, object expected)
        {
            Within(TimeSpan.FromSeconds(10), () => AwaitAssert(() =>
            {
                _replicator.Tell(Dsl.Get(key, ReadLocal.Instance));
                var g = ExpectMsg <GetSuccess>().Get(key);
                object value;
                switch (g)
                {
                case GCounter counter:
                    value = counter.Value;
                    break;

                case PNCounter pnCounter:
                    value = pnCounter.Value;
                    break;

                case GSet <string> set:
                    value = set.Elements;
                    break;

                case ORSet <string> orSet:
                    value = orSet.Elements;
                    break;

                default:
                    throw new ArgumentException("input doesn't match");
                }

                value.ShouldBe(expected);
            }));
        }
        private void AssertValue(IKey <IReplicatedData> key, object expected)
        {
            Within(TimeSpan.FromSeconds(10), () => AwaitAssert(() =>
            {
                _replicator.Tell(Dsl.Get(key, ReadLocal.Instance));
                var g = ExpectMsg <GetSuccess>().Get(key);
                object value;
                if (g is GCounter)
                {
                    value = ((GCounter)g).Value;
                }
                else if (g is PNCounter)
                {
                    value = ((PNCounter)g).Value;
                }
                else if (g is GSet <string> )
                {
                    value = ((GSet <string>)g).Elements;
                }
                else if (g is ORSet <string> )
                {
                    value = ((ORSet <string>)g).Elements;
                }
                else
                {
                    throw new ArgumentException("input doesn't match");
                }

                value.ShouldBe(expected);
            }));
        }
Example #10
0
        private static async Task Main()
        {
            Console.WriteLine("Put the ddata mdb file in a folder called cluster-data in the application root folder. Press a key when done");
            Console.Read();

            var cfg = ConfigurationFactory.ParseString(File.ReadAllText("HOCON"))
                      .WithFallback(DistributedData.DefaultConfig());

            var originalColour = Console.ForegroundColor;

            var sys           = ActorSystem.Create("test", cfg);
            var dd            = DistributedData.Get(sys);
            int emptyKeyCount = 0;

            var resp = await dd.Replicator.Ask <GetKeysIdsResult>(Dsl.GetKeyIds);

            foreach (var resultKey in resp.Keys)
            {
                var key = new ORSetKey <string>($"{resultKey}");

                var keyResp = await dd.Replicator.Ask <IGetResponse>(Dsl.Get(key));

                Console.ForegroundColor = ConsoleColor.Green;
                if (keyResp.Get(key).Elements.Count == 0)
                {
                    emptyKeyCount++;
                }

                Console.WriteLine($"{key.Id}\t{string.Join<string>(",", keyResp.Get(key).Elements)}");
            }

            Console.ForegroundColor = ConsoleColor.Yellow;
            Console.WriteLine($"Finished loading {resp.Keys.Count} keys. There were {emptyKeyCount} empty keys");
            Console.ForegroundColor = originalColour;
        }
Example #11
0
        public void Insert_from_5_nodes_should_replicate_values_when_all_nodes_connected()
        {
            var key = new ORSetKey <int>("A");

            RunOn(() =>
            {
                var writeProbe = CreateTestProbe();
                var writeAcks  = MyData.Select(i =>
                {
                    SleepDelay();
                    _replicator.Tell(Dsl.Update(key, ORSet <int> .Empty, WriteLocal.Instance, i, x => x.Add(_cluster.SelfUniqueAddress, i)), writeProbe.Ref);
                    return(writeProbe.ReceiveOne(TimeSpan.FromSeconds(3)));
                }).ToArray();
                var successWriteAcks = writeAcks.OfType <Replicator.UpdateSuccess>().ToArray();
                var failureWriteAcks = writeAcks.OfType <Replicator.IUpdateFailure>().ToArray();
                successWriteAcks.Select(x => (int)x.Request).ShouldBe(MyData.ToArray());
                successWriteAcks.Length.ShouldBe(MyData.Count());
                failureWriteAcks.ShouldBe(new Replicator.IUpdateFailure[0]);
                (successWriteAcks.Length + failureWriteAcks.Length).ShouldBe(MyData.Count());

                // eventually all nodes will have the data
                Within(TimeSpan.FromSeconds(15), () =>
                {
                    AwaitAssert(() =>
                    {
                        var readProbe = CreateTestProbe();
                        _replicator.Tell(Dsl.Get(key, ReadLocal.Instance), readProbe.Ref);
                        var result = readProbe.ExpectMsg <Replicator.GetSuccess>(g => Equals(g.Key, key)).Get(key);
                        result.Elements.ShouldBe(_expectedData);
                    });
                });
            }, _nodes.ToArray());

            EnterBarrier("after-test-1");
        }
Example #12
0
        public void Cluster_CRDT_should_work_in_2_node_cluster()
        {
            RunOn(() =>
            {
                // start with 20 on both nodes
                _replicator.Tell(Dsl.Update(KeyB, GCounter.Empty, WriteLocal.Instance, x => x.Increment(_cluster, 20)));
                ExpectMsg(new UpdateSuccess(KeyB, null));

                // add 1 on both nodes using WriteTwo
                _replicator.Tell(Dsl.Update(KeyB, GCounter.Empty, _writeTwo, x => x.Increment(_cluster, 1)));
                ExpectMsg(new UpdateSuccess(KeyB, null));

                // the total, after replication should be 42
                AwaitAssert(() =>
                {
                    _replicator.Tell(Dsl.Get(KeyB, _readTwo));
                    var c = ExpectMsg <GetSuccess>(g => Equals(g.Key, KeyB)).Get(KeyB);
                    c.Value.ShouldBe(42);
                });
            }, _first, _second);

            EnterBarrier("update-42");

            RunOn(() =>
            {
                // add 1 on both nodes using WriteAll
                _replicator.Tell(Dsl.Update(KeyB, GCounter.Empty, _writeAll, x => x.Increment(_cluster, 1)));
                ExpectMsg(new UpdateSuccess(KeyB, null));

                // the total, after replication should be 44
                AwaitAssert(() =>
                {
                    _replicator.Tell(Dsl.Get(KeyB, _readAll));
                    var c = ExpectMsg <GetSuccess>(g => Equals(g.Key, KeyB)).Get(KeyB);
                    c.Value.ShouldBe(44);
                });
            }, _first, _second);

            EnterBarrier("update-44");

            RunOn(() =>
            {
                // add 1 on both nodes using WriteMajority
                _replicator.Tell(Dsl.Update(KeyB, GCounter.Empty, _writeMajority, x => x.Increment(_cluster, 1)));
                ExpectMsg(new UpdateSuccess(KeyB, null));

                // the total, after replication should be 46
                AwaitAssert(() =>
                {
                    _replicator.Tell(Dsl.Get(KeyB, _readMajority));
                    var c = ExpectMsg <GetSuccess>(g => Equals(g.Key, KeyB)).Get(KeyB);
                    c.Value.ShouldBe(46);
                });
            }, _first, _second);

            EnterBarrierAfterTestStep();
        }
Example #13
0
 protected override void PreStart()
 {
     _pruningToken =
         Context.System.Scheduler.ScheduleTellRepeatedlyCancelable(
             PruningConfiguration.PruningInterval,
             PruningConfiguration.PruningInterval, Replicator.Replicator,
             Dsl.Get(
                 new LWWDictionaryKey <string, DeduplicationState>(
                     ReplicatorKey), request: new PurgeStateQuery()), Self);
 }
Example #14
0
 /// <summary>
 /// On one of the nodes the data has been updated by the pruning, client can update anyway
 /// </summary>
 private void UpdateAfterPruning(int expectedValue)
 {
     _replicator.Tell(Dsl.Update(KeyA, GCounter.Empty, new WriteAll(_timeout), x => x.Increment(_cluster.SelfUniqueAddress, 1)));
     ExpectMsg <Replicator.UpdateSuccess>(msg =>
     {
         _replicator.Tell(Dsl.Get(KeyA, ReadLocal.Instance));
         var retrieved = ExpectMsg <Replicator.GetSuccess>().Get(KeyA);
         retrieved.Value.ShouldBe(expectedValue);
     });
 }
Example #15
0
        public void Durable_CRDT_should_work_in_a_multi_node_cluster()
        {
            Join(second, first);

            var r = NewReplicator(Sys);

            Within(TimeSpan.FromSeconds(10), () =>
            {
                AwaitAssert(() =>
                {
                    r.Tell(Dsl.GetReplicaCount);
                    ExpectMsg(new ReplicaCount(2));
                });
            });

            EnterBarrier("both-initialized");

            r.Tell(Dsl.Update(keyA, GCounter.Empty, writeTwo, c => c.Increment(cluster)));
            ExpectMsg(new UpdateSuccess(keyA, null));

            r.Tell(Dsl.Update(keyC, ORSet <string> .Empty, writeTwo, c => c.Add(cluster, Myself.Name)));
            ExpectMsg(new UpdateSuccess(keyC, null));

            EnterBarrier("update-done-" + testStepCounter);

            r.Tell(Dsl.Get(keyA, readTwo));
            ExpectMsg <GetSuccess>().Get(keyA).Value.ShouldBe(2UL);

            r.Tell(Dsl.Get(keyC, readTwo));
            ExpectMsg <GetSuccess>().Get(keyC).Elements.ShouldBe(ImmutableHashSet.CreateRange(new[] { first.Name, second.Name }));

            EnterBarrier("values-verified-" + testStepCounter);

            Watch(r);
            Sys.Stop(r);
            ExpectTerminated(r);

            var r2 = default(IActorRef);

            AwaitAssert(() => r2 = NewReplicator(Sys)); // try until name is free
            AwaitAssert(() =>
            {
                r2.Tell(Dsl.GetKeyIds);
                ExpectMsg <GetKeysIdsResult>().Keys.ShouldNotBe(ImmutableHashSet <string> .Empty);
            });

            r2.Tell(Dsl.Get(keyA, ReadLocal.Instance));
            ExpectMsg <GetSuccess>().Get(keyA).Value.ShouldBe(2UL);

            r2.Tell(Dsl.Get(keyC, ReadLocal.Instance));
            ExpectMsg <GetSuccess>().Get(keyC).Elements.ShouldBe(ImmutableHashSet.CreateRange(new[] { first.Name, second.Name }));

            EnterBarrierAfterTestStep();
        }
 private void AssertDeleted(IKey <IReplicatedData> key)
 {
     Within(TimeSpan.FromSeconds(5), () =>
     {
         AwaitAssert(() =>
         {
             _replicator.Tell(Dsl.Get(key, ReadLocal.Instance));
             ExpectMsg(new DataDeleted(key));
         });
     });
 }
Example #17
0
        public void Cluster_CRDT_should_support_prefer_oldest_members()
        {
            // disable gossip and delta replication to only verify the write and read operations
            var oldestReplicator = Sys.ActorOf(
                Replicator.Props(
                    ReplicatorSettings.Create(Sys).WithPreferOldest(true).WithGossipInterval(TimeSpan.FromMinutes(1))),//.withDeltaCrdtEnabled(false)),
                "oldestReplicator");

            Within(TimeSpan.FromSeconds(5), () =>
            {
                var countProbe = CreateTestProbe();
                AwaitAssert(() =>
                {
                    oldestReplicator.Tell(GetReplicaCount.Instance, countProbe.Ref);
                    countProbe.ExpectMsg(new ReplicaCount(3));
                });
            });
            EnterBarrier("oldest-replicator-started");

            var probe = CreateTestProbe();

            RunOn(() =>
            {
                oldestReplicator.Tell(
                    Dsl.Update(KeyK, new LWWRegister <string>(Cluster.SelfUniqueAddress, "0"), _writeTwo, a => a.WithValue(Cluster.SelfUniqueAddress, "1")),
                    probe.Ref);
                probe.ExpectMsg(new UpdateSuccess(KeyK, null));
            }, _second);
            EnterBarrier("updated-1");

            RunOn(() =>
            {
                // replicated to oldest
                oldestReplicator.Tell(new Get(KeyK, ReadLocal.Instance), probe.Ref);
                var msg = probe.ExpectMsg <GetSuccess>(m => m.Data is LWWRegister <string>);
                ((LWWRegister <string>)msg.Data).Value.Should().Be("1");
                //probe.ExpectMsg<GetSuccess[LWWRegister[String]]>.dataValue.value should === ("1");
            }, _first);

            RunOn(() =>
            {
                // not replicated to third (not among the two oldest)
                oldestReplicator.Tell(Dsl.Get(KeyK, ReadLocal.Instance), probe.Ref);
                probe.ExpectMsg(new NotFound(KeyK, null));

                // read from oldest
                oldestReplicator.Tell(Dsl.Get(KeyK, _readTwo), probe.Ref);
                var msg = probe.ExpectMsg <GetSuccess>(m => m.Data is LWWRegister <string>);
                ((LWWRegister <string>)msg.Data).Value.Should().Be("1");
                //probe.ExpectMsg<GetSuccess[LWWRegister[String]]>.dataValue.value should === ("1");
            }, _third);

            EnterBarrierAfterTestStep();
        }
Example #18
0
        public void Durable_CRDT_should_work_in_a_single_node_cluster()
        {
            Join(_first, _first);

            RunOn(() =>
            {
                var r = NewReplicator();
                Within(TimeSpan.FromSeconds(10), () =>
                {
                    AwaitAssert(() =>
                    {
                        r.Tell(Dsl.GetReplicaCount);
                        ExpectMsg(new ReplicaCount(1));
                    });
                });

                r.Tell(Dsl.Get(_keyA, ReadLocal.Instance));
                ExpectMsg(new NotFound(_keyA, null));

                TellUpdate(r, _keyA, WriteLocal.Instance, new PocoObject("Id_1", 1));
                TellUpdate(r, _keyA, WriteLocal.Instance, new PocoObject("Id_1", 2));
                TellUpdate(r, _keyA, WriteLocal.Instance, new PocoObject("Id_1", 3));

                ExpectMsg(new UpdateSuccess(_keyA, null));
                ExpectMsg(new UpdateSuccess(_keyA, null));
                ExpectMsg(new UpdateSuccess(_keyA, null));

                Watch(r);
                Sys.Stop(r);
                ExpectTerminated(r);

                var r2 = default(IActorRef);
                AwaitAssert(() => r2 = NewReplicator()); // try until name is free

                // note that it will stash the commands until loading completed
                r2.Tell(Dsl.Get(_keyA, ReadLocal.Instance));
                var success = ExpectMsg <GetSuccess>().Get(_keyA);
                success.TryGetValue("Id_1", out var value).Should().BeTrue();
                value.TransactionId.Should().Be("Id_1");
                value.Created.Should().Be(3);

                Watch(r2);
                Sys.Stop(r2);
                ExpectTerminated(r2);
            }, _first);

            EnterBarrierAfterTestStep();
        }
Example #19
0
        public void Durable_CRDT_should_work_in_a_single_node_cluster()
        {
            Join(first, second);

            RunOn(() =>
            {
                var r = NewReplicator(Sys);
                Within(TimeSpan.FromSeconds(10), () =>
                {
                    AwaitAssert(() =>
                    {
                        r.Tell(Dsl.GetReplicaCount);
                        ExpectMsg(new ReplicaCount(1));
                    });
                });

                r.Tell(Dsl.Get(keyA, ReadLocal.Instance));
                ExpectMsg(new NotFound(keyA, null));

                r.Tell(Dsl.Update(keyA, GCounter.Empty, WriteLocal.Instance, c => c.Increment(cluster)));
                r.Tell(Dsl.Update(keyA, GCounter.Empty, WriteLocal.Instance, c => c.Increment(cluster)));
                r.Tell(Dsl.Update(keyA, GCounter.Empty, WriteLocal.Instance, c => c.Increment(cluster)));

                ExpectMsg(new UpdateSuccess(keyA, null));
                ExpectMsg(new UpdateSuccess(keyA, null));
                ExpectMsg(new UpdateSuccess(keyA, null));

                Watch(r);
                Sys.Stop(r);
                ExpectTerminated(r);

                var r2 = default(IActorRef);
                AwaitAssert(() => r2 = NewReplicator(Sys)); // try until name is free

                // note that it will stash the commands until loading completed
                r2.Tell(Dsl.Get(keyA, ReadLocal.Instance));
                ExpectMsg <GetSuccess>().Get(keyA).Value.ShouldBe(3UL);

                Watch(r2);
                Sys.Stop(r2);
                ExpectTerminated(r2);
            }, first);

            EnterBarrierAfterTestStep();
        }
Example #20
0
        public async Task <IEnumerable <MatchingActor> > GetMatchingActorsAsync(M message, IMessagePatternFactory <P> messagePatternFactory)
        {
            var replicator        = DistributedData.Get(ActorSystem).Replicator;
            GetKeysIdsResult keys = await replicator.Ask <GetKeysIdsResult>(Dsl.GetKeyIds);

            var matchingActors = new List <MatchingActor>();

            foreach (var node in keys.Keys)
            {
                var setKey      = new LWWRegisterKey <ActorProps[]>(node);
                var getResponse = await replicator.Ask <IGetResponse>(Dsl.Get(setKey, ReadLocal.Instance));

                if (!getResponse.IsSuccessful)
                {
                    throw new Exception($"cannot get message patterns for node {node}");
                }
                var actorPropsList = getResponse.Get(setKey).Value;

                foreach (var actorProps in actorPropsList)
                {
                    var path                  = actorProps.Path;
                    var matchingPatterns      = actorProps.Patterns.Where(pattern => pattern.Match(message));
                    int matchingPatternsCount = matchingPatterns.Count();
                    if (matchingPatternsCount > 0)
                    {
                        var matchingPattern = matchingPatterns.First();
                        if (matchingPatternsCount > 1)
                        {
                            Logger.Warning("For actor {0}, found {1} patterns matching message {2}. Taking first one = {3}", path, matchingPatternsCount, message, matchingPattern);
                        }
                        matchingActors.Add(
                            new MatchingActor
                        {
                            Path           = path,
                            IsSecondary    = matchingPattern.IsSecondary,
                            MatchingScore  = matchingPattern.Conjuncts.Length,
                            MistrustFactor = actorProps.MistrustFactor
                        });
                    }
                }
            }
            return(matchingActors);
        }
Example #21
0
        public void Durable_CRDT_should_be_durable_after_gossip_update()
        {
            var r = NewReplicator();

            RunOn(() =>
            {
                Log.Debug("sending message with sender: {}", ActorCell.GetCurrentSelfOrNoSender());
                r.Tell(Dsl.Update(_keyC, ORSet <string> .Empty, WriteLocal.Instance, c => c.Add(_cluster, Myself.Name)));
                ExpectMsg(new UpdateSuccess(_keyC, null));
            }, _first);

            RunOn(() =>
            {
                r.Tell(Dsl.Subscribe(_keyC, TestActor));
                ExpectMsg <Changed>().Get(_keyC).Elements.ShouldBe(ImmutableHashSet.Create(_first.Name));

                // must do one more roundtrip to be sure that it keyB is stored, since Changed might have
                // been sent out before storage
                TellUpdate(r, _keyA, WriteLocal.Instance, new PocoObject("Id_1", 3));
                ExpectMsg(new UpdateSuccess(_keyA, null));

                Watch(r);
                Sys.Stop(r);
                ExpectTerminated(r);

                var r2 = default(IActorRef);
                AwaitAssert(() => r2 = NewReplicator()); // try until name is free
                AwaitAssert(() =>
                {
                    r2.Tell(Dsl.GetKeyIds);
                    ExpectMsg <GetKeysIdsResult>().Keys.ShouldNotBe(ImmutableHashSet <string> .Empty);
                });

                r2.Tell(Dsl.Get(_keyC, ReadLocal.Instance));
                ExpectMsg <GetSuccess>().Get(_keyC).Elements.ShouldBe(ImmutableHashSet.Create(_first.Name));
            }, _second);

            EnterBarrierAfterTestStep();
        }
Example #22
0
        public void Cluster_CRDT_should_read_repair_happens_before_GetSuccess()
        {
            RunOn(() =>
            {
                _replicator.Tell(Dsl.Update(KeyG, ORSet <string> .Empty, _writeTwo, x => x
                                            .Add(_cluster, "a")
                                            .Add(_cluster, "b")));
                ExpectMsg <UpdateSuccess>();
            }, _first);

            EnterBarrier("a-b-added-to-G");

            RunOn(() =>
            {
                _replicator.Tell(Dsl.Get(KeyG, _readAll));
                ExpectMsg <GetSuccess>(g => Equals(g.Key, KeyG)).Get(KeyG).Elements.SetEquals(new[] { "a", "b" });
                _replicator.Tell(Dsl.Get(KeyG, ReadLocal.Instance));
                ExpectMsg <GetSuccess>(g => Equals(g.Key, KeyG)).Get(KeyG).Elements.SetEquals(new[] { "a", "b" });
            }, _second);

            EnterBarrierAfterTestStep();
        }
Example #23
0
        public void Durable_CRDT_should_be_durable_after_gossip_update()
        {
            var r = NewReplicator(Sys);

            RunOn(() =>
            {
                r.Tell(Dsl.Update(keyC, ORSet <string> .Empty, WriteLocal.Instance, c => c.Add(cluster, Myself.Name)));
                ExpectMsg(new UpdateSuccess(keyC, null));
            }, first);

            RunOn(() =>
            {
                r.Tell(Dsl.Subscribe(keyC, TestActor));
                ExpectMsg <Changed>().Get(keyC).Elements.ShouldBe(ImmutableHashSet.Create(first.Name));

                // must do one more roundtrip to be sure that it keyB is stored, since Changed might have
                // been sent out before storage
                r.Tell(Dsl.Update(keyA, GCounter.Empty, WriteLocal.Instance, c => c.Increment(cluster)));
                ExpectMsg(new UpdateSuccess(keyA, null));

                Watch(r);
                Sys.Stop(r);
                ExpectTerminated(r);

                var r2 = default(IActorRef);
                AwaitAssert(() => r2 = NewReplicator(Sys));
                AwaitAssert(() =>
                {
                    r2.Tell(Dsl.GetKeyIds);
                    ExpectMsg <GetKeysIdsResult>().Keys.ShouldNotBe(ImmutableHashSet <string> .Empty);
                });

                r2.Tell(Dsl.Get(keyC, ReadLocal.Instance));
                ExpectMsg <GetSuccess>().Get(keyC).Elements.ShouldBe(ImmutableHashSet.Create(first.Name));
            }, second);

            EnterBarrierAfterTestStep();
        }
Example #24
0
        public void Insert_from_5_nodes_should_write_to_majority_during_3_and_2_partition_and_read_from_majority_after_partition()
        {
            var key           = new ORSetKey <int>("D");
            var readMajority  = new ReadMajority(_timeout);
            var writeMajority = new WriteMajority(_timeout);

            RunOn(() =>
            {
                SleepBeforePartition();

                foreach (var a in new List <RoleName> {
                    N1, N4, N5
                })
                {
                    foreach (var b in new List <RoleName> {
                        N2, N3
                    })
                    {
                        TestConductor.Blackhole(a, b, ThrottleTransportAdapter.Direction.Both).Wait(TimeSpan.FromSeconds(3));
                    }
                }

                SleepDuringPartition();

                foreach (var a in new List <RoleName> {
                    N1, N4, N5
                })
                {
                    foreach (var b in new List <RoleName> {
                        N2, N3
                    })
                    {
                        TestConductor.PassThrough(a, b, ThrottleTransportAdapter.Direction.Both).Wait(TimeSpan.FromSeconds(3));
                    }
                }

                EnterBarrier("partition-healed-4");
            }, Controller);

            RunOn(() =>
            {
                var writeProbe = CreateTestProbe();
                var writeAcks  = MyData.Select(i =>
                {
                    SleepDelay();
                    _replicator.Tell(Dsl.Update(key, ORSet <int> .Empty, writeMajority, i, x => x.Add(_cluster.SelfUniqueAddress, i)), writeProbe.Ref);
                    return(writeProbe.ReceiveOne(_timeout.Add(TimeSpan.FromSeconds(1))));
                }).ToArray();
                var successWriteAcks = writeAcks.OfType <Replicator.UpdateSuccess>().ToArray();
                var failureWriteAcks = writeAcks.OfType <Replicator.IUpdateFailure>().ToArray();

                RunOn(() =>
                {
                    successWriteAcks.Select(x => (int)x.Request).ShouldBe(MyData.ToArray());
                    successWriteAcks.Length.ShouldBe(MyData.Count());
                    failureWriteAcks.ShouldBe(new Replicator.IUpdateFailure[0]);
                }, N1, N4, N5);

                RunOn(() =>
                {
                    // without delays all could teoretically have been written before the blackhole
                    if (_delayMillis != 0)
                    {
                        failureWriteAcks.ShouldNotBe(new Replicator.IUpdateFailure[0]);
                    }
                }, N2, N3);

                (successWriteAcks.Length + failureWriteAcks.Length).ShouldBe(MyData.Count());

                EnterBarrier("partition-healed-4");

                // on the 2 node side, read from majority of nodes is enough to read all writes
                RunOn(() =>
                {
                    var readProbe = CreateTestProbe();
                    _replicator.Tell(Dsl.Get(key, readMajority), readProbe.Ref);
                    var result = readProbe.ExpectMsg <Replicator.GetSuccess>(g => Equals(g.Key, key)).Get(key);
                    result.Elements.ShouldBe(_expectedData);
                }, N2, N3);

                // but on the 3 node side, read from majority doesn't mean that we are guaranteed to see
                // the writes from the other side, yet

                // eventually all nodes will have the data
                Within(TimeSpan.FromSeconds(15), () => AwaitAssert(() =>
                {
                    var readProbe = CreateTestProbe();
                    _replicator.Tell(Dsl.Get(key, ReadLocal.Instance), readProbe.Ref);
                    var result = readProbe.ExpectMsg <Replicator.GetSuccess>(g => Equals(g.Key, key)).Get(key);
                    result.Elements.ShouldBe(_expectedData);
                }));
            }, _nodes.ToArray());

            EnterBarrier("after-test-4");
        }
Example #25
0
        public void Cluster_CRDT_should_support_majority_quorum_write_and_read_with_3_nodes_with_1_unreachable()
        {
            Join(_third, _first);

            RunOn(() =>
            {
                Within(TimeSpan.FromSeconds(10), () => AwaitAssert(() =>
                {
                    _replicator.Tell(Dsl.GetReplicaCount);
                    ExpectMsg(new ReplicaCount(3));
                }));
            }, _first, _second, _third);

            EnterBarrier("3-nodes");

            RunOn(() =>
            {
                _replicator.Tell(Dsl.Update(KeyE, GCounter.Empty, _writeMajority, x => x.Increment(_cluster, 50)));
                ExpectMsg(new UpdateSuccess(KeyE, null));
            }, _first, _second, _third);

            EnterBarrier("write-initial-majority");

            RunOn(() =>
            {
                _replicator.Tell(Dsl.Get(KeyE, _readMajority));
                var c150 = ExpectMsg <GetSuccess>(g => Equals(g.Key, KeyE)).Get(KeyE);
                c150.Value.ShouldBe(150);
            }, _first, _second, _third);

            EnterBarrier("read-initial-majority");

            RunOn(() =>
            {
                TestConductor.Blackhole(_first, _third, ThrottleTransportAdapter.Direction.Both).Wait(TimeSpan.FromSeconds(5));
                TestConductor.Blackhole(_second, _third, ThrottleTransportAdapter.Direction.Both).Wait(TimeSpan.FromSeconds(5));
            }, _first);

            EnterBarrier("blackhole-third");

            RunOn(() =>
            {
                _replicator.Tell(Dsl.Update(KeyE, GCounter.Empty, WriteLocal.Instance, x => x.Increment(_cluster, 1)));
                ExpectMsg(new UpdateSuccess(KeyE, null));
            }, _second);

            EnterBarrier("local-update-from-second");

            RunOn(() =>
            {
                // ReadMajority should retrive the previous update from second, before applying the modification
                var probe1 = CreateTestProbe();
                var probe2 = CreateTestProbe();
                _replicator.Tell(Dsl.Get(KeyE, _readMajority), probe2.Ref);
                probe2.ExpectMsg <GetSuccess>();
                _replicator.Tell(Dsl.Update(KeyE, GCounter.Empty, _writeMajority, data =>
                {
                    probe1.Ref.Tell(data.Value);
                    return(data.Increment(_cluster, 1));
                }), probe2.Ref);

                // verify read your own writes, without waiting for the UpdateSuccess reply
                // note that the order of the replies are not defined, and therefore we use separate probes
                var probe3 = CreateTestProbe();
                _replicator.Tell(Dsl.Get(KeyE, _readMajority), probe3.Ref);
                probe1.ExpectMsg(151);
                probe2.ExpectMsg(new UpdateSuccess(KeyE, null));
                var c152 = ExpectMsg <GetSuccess>(g => Equals(g.Key, KeyE)).Get(KeyE);
                c152.Value.ShouldBe(152);
            }, _first);

            EnterBarrier("majority-update-from-first");

            RunOn(() =>
            {
                var probe1 = CreateTestProbe();
                _replicator.Tell(Dsl.Get(KeyE, _readMajority), probe1.Ref);
                probe1.ExpectMsg <GetSuccess>();
                _replicator.Tell(Dsl.Update(KeyE, GCounter.Empty, _writeMajority, 153, x => x.Increment(_cluster, 1)), probe1.Ref);

                // verify read your own writes, without waiting for the UpdateSuccess reply
                // note that the order of the replies are not defined, and therefore we use separate probes
                var probe2 = CreateTestProbe();
                _replicator.Tell(Dsl.Update(KeyE, GCounter.Empty, _writeMajority, 154, x => x.Increment(_cluster, 1)), probe2.Ref);
                var probe3 = CreateTestProbe();
                _replicator.Tell(Dsl.Update(KeyE, GCounter.Empty, _writeMajority, 155, x => x.Increment(_cluster, 1)), probe3.Ref);
                var probe5 = CreateTestProbe();
                _replicator.Tell(Dsl.Get(KeyE, _readMajority), probe5.Ref);
                probe1.ExpectMsg(new UpdateSuccess(KeyE, 153));
                probe2.ExpectMsg(new UpdateSuccess(KeyE, 154));
                probe3.ExpectMsg(new UpdateSuccess(KeyE, 155));
                var c155 = probe5.ExpectMsg <GetSuccess>(g => Equals(g.Key, KeyE)).Get(KeyE);
                c155.Value.ShouldBe(155);
            }, _second);

            EnterBarrier("majority-update-from-second");

            RunOn(() =>
            {
                _replicator.Tell(Dsl.Get(KeyE2, _readAll, 998));
                ExpectMsg(new GetFailure(KeyE2, 998), _timeOut.Add(TimeSpan.FromSeconds(1)));
                _replicator.Tell(Dsl.Get(KeyE2, Dsl.ReadLocal));
                ExpectMsg(new NotFound(KeyE2, null));
            }, _first, _second);

            EnterBarrier("read-all-fail-update");

            RunOn(() =>
            {
                TestConductor.PassThrough(_first, _third, ThrottleTransportAdapter.Direction.Both).Wait(TimeSpan.FromSeconds(5));
                TestConductor.PassThrough(_second, _third, ThrottleTransportAdapter.Direction.Both).Wait(TimeSpan.FromSeconds(5));
            }, _first);

            EnterBarrier("passThrough-third");

            RunOn(() =>
            {
                _replicator.Tell(Dsl.Get(KeyE, _readMajority));

                var c155 = ExpectMsg <GetSuccess>(g => Equals(g.Key, KeyE)).Get(KeyE);
                c155.Value.ShouldBe(155);
            }, _third);

            EnterBarrierAfterTestStep();
        }
Example #26
0
        public void Cluster_CRDT_should_converge_after_partition()
        {
            RunOn(() =>
            {
                _replicator.Tell(Dsl.Update(KeyD, GCounter.Empty, _writeTwo, x => x.Increment(_cluster, 40)));
                ExpectMsg(new UpdateSuccess(KeyD, null));

                TestConductor.Blackhole(_first, _second, ThrottleTransportAdapter.Direction.Both)
                .Wait(TimeSpan.FromSeconds(10));
            }, _first);

            EnterBarrier("blackhole-first-second");

            RunOn(() =>
            {
                _replicator.Tell(Dsl.Get(KeyD, ReadLocal.Instance));
                var c40 = ExpectMsg <GetSuccess>(g => Equals(g.Key, KeyD)).Get(KeyD);
                c40.Value.ShouldBe(40);

                _replicator.Tell(Dsl.Update(KeyD, GCounter.Empty.Increment(_cluster, 1), _writeTwo, x => x.Increment(_cluster, 1)));
                ExpectMsg(new UpdateTimeout(KeyD, null), _timeOut.Add(TimeSpan.FromSeconds(1)));
                _replicator.Tell(Dsl.Update(KeyD, GCounter.Empty, _writeTwo, x => x.Increment(_cluster, 1)));
                ExpectMsg(new UpdateTimeout(KeyD, null), _timeOut.Add(TimeSpan.FromSeconds(1)));
            }, _first, _second);

            RunOn(() =>
            {
                //TODO: for some reason this RunOn never gets called
                for (int i = 1; i <= 30; i++)
                {
                    var n     = i;
                    var keydn = new GCounterKey("D" + n);
                    _replicator.Tell(Dsl.Update(keydn, GCounter.Empty, WriteLocal.Instance, x => x.Increment(_cluster, n)));
                    ExpectMsg(new UpdateSuccess(keydn, null));
                }
            }, _first);

            EnterBarrier("updates-during-partion");

            RunOn(() =>
            {
                TestConductor.PassThrough(_first, _second, ThrottleTransportAdapter.Direction.Both)
                .Wait(TimeSpan.FromSeconds(5));
            }, _first);

            EnterBarrier("passThrough-first-second");

            RunOn(() =>
            {
                _replicator.Tell(Dsl.Get(KeyD, _readTwo));
                var c44 = ExpectMsg <GetSuccess>(g => Equals(g.Key, KeyD)).Get(KeyD);
                c44.Value.ShouldBe(44);

                Within(TimeSpan.FromSeconds(10), () =>
                       AwaitAssert(() =>
                {
                    for (int i = 1; i <= 30; i++)
                    {
                        var keydn = new GCounterKey("D" + i);
                        _replicator.Tell(Dsl.Get(keydn, ReadLocal.Instance));
                        ExpectMsg <GetSuccess>(g => Equals(g.Key, keydn)).Get(keydn).Value.ShouldBe(i);
                    }
                }));
            }, _first, _second);

            EnterBarrierAfterTestStep();
        }
Example #27
0
        public void Cluster_CRDT_should_be_replicated_after_successful_update()
        {
            var changedProbe = CreateTestProbe();

            RunOn(() =>
            {
                _replicator.Tell(Dsl.Subscribe(KeyC, changedProbe.Ref));
            }, _first, _second);

            RunOn(() =>
            {
                _replicator.Tell(Dsl.Update(KeyC, GCounter.Empty, _writeTwo, x => x.Increment(_cluster, 30)));
                ExpectMsg(new UpdateSuccess(KeyC, null));
                changedProbe.ExpectMsg <Changed>(c => Equals(c.Key, KeyC)).Get(KeyC).Value.ShouldBe(30);

                _replicator.Tell(Dsl.Update(KeyY, GCounter.Empty, _writeTwo, x => x.Increment(_cluster, 30)));
                ExpectMsg(new UpdateSuccess(KeyY, null));

                _replicator.Tell(Dsl.Update(KeyZ, GCounter.Empty, _writeMajority, x => x.Increment(_cluster, 30)));
                ExpectMsg(new UpdateSuccess(KeyZ, null));
            }, _first);

            EnterBarrier("update-c30");

            RunOn(() =>
            {
                _replicator.Tell(Dsl.Get(KeyC, ReadLocal.Instance));
                var c30 = ExpectMsg <GetSuccess>(c => Equals(c.Key, KeyC)).Get(KeyC);
                c30.Value.ShouldBe(30);
                changedProbe.ExpectMsg <Changed>(c => Equals(c.Key, KeyC)).Get(KeyC).Value.ShouldBe(30);

                // replicate with gossip after WriteLocal
                _replicator.Tell(Dsl.Update(KeyC, GCounter.Empty, WriteLocal.Instance, x => x.Increment(_cluster, 1)));
                ExpectMsg(new UpdateSuccess(KeyC, null));
                changedProbe.ExpectMsg <Changed>(c => Equals(c.Key, KeyC)).Get(KeyC).Value.ShouldBe(31);

                _replicator.Tell(Dsl.Delete(KeyY, WriteLocal.Instance, 777));
                ExpectMsg(new DeleteSuccess(KeyY, 777));

                _replicator.Tell(Dsl.Get(KeyZ, _readMajority));
                ExpectMsg <GetSuccess>(c => Equals(c.Key, KeyZ)).Get(KeyZ).Value.ShouldBe(30);
            }, _second);

            EnterBarrier("update-c31");

            RunOn(() =>
            {
                // KeyC and deleted KeyY should be replicated via gossip to the other node
                Within(TimeSpan.FromSeconds(5), () =>
                {
                    AwaitAssert(() =>
                    {
                        _replicator.Tell(Dsl.Get(KeyC, ReadLocal.Instance));
                        var c = ExpectMsg <GetSuccess>(g => Equals(g.Key, KeyC)).Get(KeyC);
                        c.Value.ShouldBe(31);

                        _replicator.Tell(Dsl.Get(KeyY, ReadLocal.Instance));
                        ExpectMsg(new DataDeleted(KeyY));
                    });
                });
                changedProbe.ExpectMsg <Changed>(c => Equals(c.Key, KeyC)).Get(KeyC).Value.ShouldBe(31);
            }, _first);

            EnterBarrier("verified-c31");

            // and also for concurrent updates
            RunOn(() =>
            {
                _replicator.Tell(Dsl.Get(KeyC, ReadLocal.Instance));
                var c31 = ExpectMsg <GetSuccess>(g => Equals(g.Key, KeyC)).Get(KeyC);
                c31.Value.ShouldBe(31);

                _replicator.Tell(Dsl.Update(KeyC, GCounter.Empty, WriteLocal.Instance, x => x.Increment(_cluster, 1)));
                ExpectMsg(new UpdateSuccess(KeyC, null));

                Within(TimeSpan.FromSeconds(5), () =>
                {
                    AwaitAssert(() =>
                    {
                        _replicator.Tell(Dsl.Get(KeyC, ReadLocal.Instance));
                        var c = ExpectMsg <GetSuccess>(g => Equals(g.Key, KeyC)).Get(KeyC);
                        c.Value.ShouldBe(33);
                    });
                });
            }, _first, _second);

            EnterBarrierAfterTestStep();
        }
Example #28
0
        public void Insert_from_5_nodes_should_replicate_values_after_partition()
        {
            var key = new ORSetKey <int>("C");

            RunOn(() =>
            {
                SleepBeforePartition();

                foreach (var a in new List <RoleName> {
                    N1, N4, N5
                })
                {
                    foreach (var b in new List <RoleName> {
                        N2, N3
                    })
                    {
                        TestConductor.Blackhole(a, b, ThrottleTransportAdapter.Direction.Both).Wait(TimeSpan.FromSeconds(3));
                    }
                }

                SleepDuringPartition();

                foreach (var a in new List <RoleName> {
                    N1, N4, N5
                })
                {
                    foreach (var b in new List <RoleName> {
                        N2, N3
                    })
                    {
                        TestConductor.PassThrough(a, b, ThrottleTransportAdapter.Direction.Both).Wait(TimeSpan.FromSeconds(3));
                    }
                }

                EnterBarrier("partition-healed-3");
            }, Controller);

            RunOn(() =>
            {
                var writeProbe = CreateTestProbe();
                var writeAcks  = MyData.Select(i =>
                {
                    SleepDelay();
                    _replicator.Tell(Dsl.Update(key, ORSet <int> .Empty, WriteLocal.Instance, i, x => x.Add(_cluster.SelfUniqueAddress, i)), writeProbe.Ref);
                    return(writeProbe.ReceiveOne(TimeSpan.FromSeconds(3)));
                }).ToArray();
                var successWriteAcks = writeAcks.OfType <Replicator.UpdateSuccess>().ToArray();
                var failureWriteAcks = writeAcks.OfType <Replicator.IUpdateFailure>().ToArray();
                successWriteAcks.Select(x => (int)x.Request).ShouldBe(MyData.ToArray());
                successWriteAcks.Length.ShouldBe(MyData.Count());
                failureWriteAcks.ShouldBe(new Replicator.IUpdateFailure[0]);
                (successWriteAcks.Length + failureWriteAcks.Length).ShouldBe(MyData.Count());

                EnterBarrier("partition-healed-3");

                // eventually all nodes will have the data
                Within(TimeSpan.FromSeconds(15), () => AwaitAssert(() =>
                {
                    var readProbe = CreateTestProbe();
                    _replicator.Tell(Dsl.Get(key, ReadLocal.Instance), readProbe.Ref);
                    var result = readProbe.ExpectMsg <Replicator.GetSuccess>(g => Equals(g.Key, key)).Get(key);
                    result.Elements.ShouldBe(_expectedData);
                }));
            }, _nodes.ToArray());

            EnterBarrier("after-test-3");
        }
Example #29
0
        public void Pruning_of_durable_CRDT_should_move_data_from_removed_node()
        {
            Join(first, first);
            Join(second, first);

            var sys2        = ActorSystem.Create(Sys.Name, Sys.Settings.Config);
            var cluster2    = Akka.Cluster.Cluster.Get(sys2);
            var replicator2 = StartReplicator(sys2);
            var probe2      = new TestProbe(sys2, new XunitAssertions());

            cluster2.Join(Node(first).Address);

            Within(TimeSpan.FromSeconds(5), () => AwaitAssert(() =>
            {
                replicator.Tell(Dsl.GetReplicaCount);
                ExpectMsg(new ReplicaCount(4));
                replicator2.Tell(Dsl.GetReplicaCount, probe2.Ref);
                probe2.ExpectMsg(new ReplicaCount(4));
            }));

            replicator.Tell(Dsl.Update(keyA, GCounter.Empty, WriteLocal.Instance, c => c.Increment(cluster)));
            ExpectMsg(new UpdateSuccess(keyA, null));

            replicator2.Tell(Dsl.Update(keyA, GCounter.Empty, WriteLocal.Instance, c => c.Increment(cluster2, 2)), probe2.Ref);
            probe2.ExpectMsg(new UpdateSuccess(keyA, null));

            EnterBarrier("updates-done");

            Within(TimeSpan.FromSeconds(10), () => AwaitAssert(() =>
            {
                replicator.Tell(Dsl.Get(keyA, new ReadAll(TimeSpan.FromSeconds(1))));
                var counter1 = ExpectMsg <GetSuccess>().Get(keyA);
                counter1.Value.ShouldBe(10UL);
                counter1.State.Count.ShouldBe(4);
            }));

            Within(TimeSpan.FromSeconds(10), () => AwaitAssert(() =>
            {
                replicator2.Tell(Dsl.Get(keyA, new ReadAll(TimeSpan.FromSeconds(1))), probe2.Ref);
                var counter2 = probe2.ExpectMsg <GetSuccess>().Get(keyA);
                counter2.Value.ShouldBe(10UL);
                counter2.State.Count.ShouldBe(4);
            }));
            EnterBarrier("get1");

            RunOn(() => cluster.Leave(cluster2.SelfAddress), first);

            Within(TimeSpan.FromSeconds(15), () => AwaitAssert(() =>
            {
                replicator.Tell(Dsl.GetReplicaCount);
                ExpectMsg(new ReplicaCount(3));
            }));
            EnterBarrier("removed");

            RunOn(() => sys2.Terminate().Wait(TimeSpan.FromSeconds(5)), first);

            Within(TimeSpan.FromSeconds(15), () =>
            {
                var values = ImmutableHashSet <int> .Empty;
                AwaitAssert(() =>
                {
                    replicator.Tell(Dsl.Get(keyA, ReadLocal.Instance));
                    var counter3 = ExpectMsg <GetSuccess>().Get(keyA);
                    var value    = counter3.Value;
                    values       = values.Add((int)value);
                    value.ShouldBe(10UL);
                    counter3.State.Count.ShouldBe(3);
                });
                values.ShouldBe(ImmutableHashSet.Create(10));
            });
            EnterBarrier("prunned");

            RunOn(() =>
            {
                var addr        = cluster2.SelfAddress;
                var sys3        = ActorSystem.Create(Sys.Name, ConfigurationFactory.ParseString(@"
                ").WithFallback(Sys.Settings.Config));
                var cluster3    = Akka.Cluster.Cluster.Get(sys3);
                var replicator3 = StartReplicator(sys3);
                var probe3      = new TestProbe(sys3, new XunitAssertions());
                cluster3.Join(Node(first).Address);

                Within(TimeSpan.FromSeconds(10), () =>
                {
                    var values = ImmutableHashSet <int> .Empty;
                    AwaitAssert(() =>
                    {
                        replicator3.Tell(Dsl.Get(keyA, ReadLocal.Instance), probe3.Ref);
                        var counter4 = probe3.ExpectMsg <GetSuccess>().Get(keyA);
                        var value    = counter4.Value;
                        values.Add((int)value);
                        value.ShouldBe(10UL);
                        counter4.State.Count.ShouldBe(3);
                    });
                    values.ShouldBe(ImmutableHashSet.Create(10));
                });

                // after merging with others
                replicator3.Tell(Dsl.Get(keyA, new ReadAll(RemainingOrDefault)));
                var counter5 = ExpectMsg <GetSuccess>().Get(keyA);
                counter5.Value.ShouldBe(10UL);
                counter5.State.Count.ShouldBe(3);
            }, first);
            EnterBarrier("sys3-started");

            replicator.Tell(Dsl.Get(keyA, new ReadAll(RemainingOrDefault)));
            var counter6 = ExpectMsg <GetSuccess>().Get(keyA);

            counter6.Value.ShouldBe(10UL);
            counter6.State.Count.ShouldBe(3);

            EnterBarrier("after-1");
        }
Example #30
0
        public void Cluster_CRDT_should_work_in_single_node_cluster()
        {
            Join(_first, _first);

            RunOn(() =>
            {
                Within(TimeSpan.FromSeconds(5.0), () =>
                {
                    _replicator.Tell(Dsl.GetReplicaCount);
                    ExpectMsg(new ReplicaCount(1));
                });

                var changedProbe = CreateTestProbe();
                _replicator.Tell(Dsl.Subscribe(KeyA, changedProbe.Ref));
                _replicator.Tell(Dsl.Subscribe(KeyX, changedProbe.Ref));

                _replicator.Tell(Dsl.Get(KeyA, ReadLocal.Instance));
                ExpectMsg(new NotFound(KeyA, null));

                var c3     = GCounter.Empty.Increment(_cluster, 3);
                var update = Dsl.Update(KeyA, GCounter.Empty, WriteLocal.Instance, x => x.Increment(_cluster, 3));
                _replicator.Tell(update);
                ExpectMsg(new UpdateSuccess(KeyA, null));
                _replicator.Tell(Dsl.Get(KeyA, ReadLocal.Instance));
                ExpectMsg(new GetSuccess(KeyA, null, c3));
                changedProbe.ExpectMsg(new Changed(KeyA, c3));

                var changedProbe2 = CreateTestProbe();
                _replicator.Tell(new Subscribe(KeyA, changedProbe2.Ref));
                changedProbe2.ExpectMsg(new Changed(KeyA, c3));


                var c4 = c3.Increment(_cluster);
                // too strong consistency level
                _replicator.Tell(Dsl.Update(KeyA, _writeTwo, x => x.Increment(_cluster)));
                ExpectMsg(new UpdateTimeout(KeyA, null), _timeOut.Add(TimeSpan.FromSeconds(1)));
                _replicator.Tell(Dsl.Get(KeyA, ReadLocal.Instance));
                ExpectMsg(new GetSuccess(KeyA, null, c4));
                changedProbe.ExpectMsg(new Changed(KeyA, c4));

                var c5 = c4.Increment(_cluster);
                // too strong consistency level
                _replicator.Tell(Dsl.Update(KeyA, _writeMajority, x => x.Increment(_cluster)));
                ExpectMsg(new UpdateSuccess(KeyA, null));
                _replicator.Tell(Dsl.Get(KeyA, _readMajority));
                ExpectMsg(new GetSuccess(KeyA, null, c5));
                changedProbe.ExpectMsg(new Changed(KeyA, c5));

                var c6 = c5.Increment(_cluster);
                _replicator.Tell(Dsl.Update(KeyA, _writeAll, x => x.Increment(_cluster)));
                ExpectMsg(new UpdateSuccess(KeyA, null));
                _replicator.Tell(Dsl.Get(KeyA, _readAll));
                ExpectMsg(new GetSuccess(KeyA, null, c6));
                changedProbe.ExpectMsg(new Changed(KeyA, c6));

                var c9 = GCounter.Empty.Increment(_cluster, 9);
                _replicator.Tell(Dsl.Update(KeyX, GCounter.Empty, WriteLocal.Instance, x => x.Increment(_cluster, 9)));
                ExpectMsg(new UpdateSuccess(KeyX, null));
                changedProbe.ExpectMsg(new Changed(KeyX, c9));
                _replicator.Tell(Dsl.Delete(KeyX, WriteLocal.Instance));
                ExpectMsg(new DeleteSuccess(KeyX));
                changedProbe.ExpectMsg(new DataDeleted(KeyX));
                _replicator.Tell(Dsl.Get(KeyX, ReadLocal.Instance));
                ExpectMsg(new DataDeleted(KeyX));
                _replicator.Tell(Dsl.Get(KeyX, _readAll));
                ExpectMsg(new DataDeleted(KeyX));
                _replicator.Tell(Dsl.Update(KeyX, WriteLocal.Instance, x => x.Increment(_cluster)));
                ExpectMsg(new DataDeleted(KeyX));
                _replicator.Tell(Dsl.Delete(KeyX, WriteLocal.Instance));
                ExpectMsg(new DataDeleted(KeyX));

                _replicator.Tell(Dsl.GetKeyIds);
                ExpectMsg(new GetKeysIdsResult(ImmutableHashSet <string> .Empty.Add("A")));
            }, _first);

            EnterBarrierAfterTestStep();
        }