private async Task ExecuteSetExpr(SetExpr expr) { var key = new ORSetKey <string>(expr.Key); try { var set = await ddata.GetAsync(key) ?? ORSet <string> .Empty; switch (expr.Symbol) { case Symbol.ADD: set = set.Add(cluster, expr.Value); break; case Symbol.REM: set = set.Remove(cluster, expr.Value); break; default: throw new NotSupportedException($"Operation {expr.Symbol} not supported on ORSet"); } await ddata.UpdateAsync(key, set, writeConsistency); var value = await ddata.GetAsync(key); Console.WriteLine($"Updated '{key}': {value}"); } catch (Exception e) { Console.WriteLine($"Couldn't perform UPDATE for {key}: {e}"); } }
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"); }
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}"); } }
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}"); } }
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; }
private void HandleMessage(CreateEventMarket selection) { var key = new ORSetKey <string>($"Event-{selection.EventId}"); var readConsistency = ReadLocal.Instance; var reply = Task.Run(() => { var result = _ddataStore.Ask <IGetResponse>(Get(key, readConsistency), TimeSpan.FromSeconds(2)); if (result.Result.IsSuccessful) { Sender.Tell(result.Result.Get(key)); } }); }
private async Task ExecuteQueryExpr(QueryExpr expr) { var key = new ORSetKey <string>(expr.Key); try { var reply = await ddata.GetAsync(key, readConsistency); Console.WriteLine($"GET '{key}': {reply?.ToString() ?? "null" }"); } catch (Exception e) { Console.WriteLine($"Couldn't receive GET for {key}: {e}"); } }
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"); }
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"); }