public async Task Publish(MultiClusterData data) { logger.Verbose("-Publish data:{0}", data); // this is (almost) always called with just one item in data to be written back // so we are o.k. with doing individual tasks for each storage read and write var tasks = new List<Task>(); if (data.Configuration != null) { Func<Task> publishconfig = async () => { var configInStorage = await tableManager.ReadConfigurationEntryAsync(); await DiffAndWriteBackConfigAsync(data.Configuration, configInStorage); }; tasks.Add(publishconfig()); } foreach (var gateway in data.Gateways.Values) { Func<Task> publishgatewayinfo = async () => { var gatewayInfoInStorage = await tableManager.ReadGatewayEntryAsync(gateway); await DiffAndWriteBackGatewayInfoAsync(gateway, gatewayInfoInStorage); }; tasks.Add(publishgatewayinfo()); } await Task.WhenAll(tasks); }
public MultiClusterData ApplyDataAndNotify(MultiClusterData data) { if (data.IsEmpty) { return(data); } MultiClusterData delta; MultiClusterData prev = this.localData; this.localData = prev.Merge(data, out delta); if (logger.IsVerbose2) { logger.Verbose2("ApplyDataAndNotify: delta {0}", delta); } if (delta.IsEmpty) { return(delta); } if (delta.Configuration != null) { // notify configuration listeners of change // code will be added in separate PR } return(delta); }
public MultiClusterData ApplyDataAndNotify(MultiClusterData data) { if (data.IsEmpty) return data; MultiClusterData delta; MultiClusterData prev = this.localData; this.localData = prev.Merge(data, out delta); if (logger.IsVerbose2) logger.Verbose2("ApplyDataAndNotify: delta {0}", delta); if (delta.IsEmpty) return delta; if (delta.Gateways.Count > 0) { // some gateways have changed ComputeAvailableGatewaysPerCluster(); } if (delta.Configuration != null) { // notify configuration listeners of change // code will be added in separate PR } return delta; }
private void AssertEffect(MultiClusterData what, MultiClusterData to, MultiClusterData expectedMerge, MultiClusterData expectedDelta = null) { MultiClusterData delta; var merge = to.Merge(what, out delta); Assert.True(CheckEquality(expectedMerge, merge)); if (expectedDelta != null) { Assert.Equal(expectedDelta, expectedDelta); } }
public async Task<MultiClusterData> Synchronize(MultiClusterData pushed) { logger.Verbose("-Synchronize pushed:{0}", pushed); try { // read the entire table from storage var entriesFromStorage = await tableManager.ReadAllEntriesAsync(); var configInStorage = entriesFromStorage.Item1; var gatewayInfoInStorage = entriesFromStorage.Item2; // diff and write back configuration var configDeltaTask = DiffAndWriteBackConfigAsync(pushed.Configuration, configInStorage); // diff and write back gateway info for each gateway appearing locally or in storage var gatewayDeltaTasks = new List<Task<GatewayEntry>>(); var allAddresses = gatewayInfoInStorage.Keys.Union(pushed.Gateways.Keys); foreach (var address in allAddresses) { GatewayEntry pushedInfo = null; pushed.Gateways.TryGetValue(address, out pushedInfo); GossipTableEntry infoInStorage = null; gatewayInfoInStorage.TryGetValue(address, out infoInStorage); gatewayDeltaTasks.Add(DiffAndWriteBackGatewayInfoAsync(pushedInfo, infoInStorage)); } // wait for all the writeback tasks to complete // these are not batched because we want them to fail individually on e-tag conflicts, not all await configDeltaTask; await Task.WhenAll(gatewayDeltaTasks); // assemble delta pieces var gw = new Dictionary<SiloAddress, GatewayEntry>(); foreach (var t in gatewayDeltaTasks) { var d = t.Result; if (d != null) gw.Add(d.SiloAddress, d); } var delta = new MultiClusterData(gw, configDeltaTask.Result); logger.Verbose("-Synchronize pulled delta:{0}", delta); return delta; } catch (Exception e) { logger.Info("-Synchronize encountered exception {0}", e); throw e; } }
private void TestAlgebraicProperties(MultiClusterData A, MultiClusterData B) { MultiClusterData D; var BB = B.Merge(A, out D); var empty = new MultiClusterData(); AssertEffect(D, B, BB, D); AssertEffect(D, BB, BB, empty); AssertEffect(D, A, A, empty); AssertEffect(BB.Minus(D), B, B, empty); AssertEffect(BB.Minus(D), A, BB); AssertEffect(B, A, BB); }
public void MultiClusterData_Configuration() { var ts1 = new DateTime(year: 2011, month: 1, day: 1); var ts2 = new DateTime(year: 2012, month: 2, day: 2); var conf1 = new MultiClusterConfiguration(ts1, new string[] { "A" }.ToList()); var conf2 = new MultiClusterConfiguration(ts2, new string[] { "A", "B", "C" }.ToList()); var gd1 = new MultiClusterData(); var gd2 = new MultiClusterData(conf1); var gd3 = new MultiClusterData(conf2); TestAlgebraicProperties(gd1, gd1); TestAlgebraicProperties(gd2, gd2); TestAlgebraicProperties(gd1, gd2); TestAlgebraicProperties(gd3, gd1); TestAlgebraicProperties(gd2, gd3); TestAlgebraicProperties(gd3, gd2); }
private bool CheckEquality(MultiClusterData one, MultiClusterData other) { if (one == null) { return(other == null); } if (other == null) { return(false); } if ((one.Configuration == null) != (other.Configuration == null)) { return(false); } if (one.Gateways.Count != other.Gateways.Count) { return(false); } if ((one.Configuration != null) && !one.Configuration.Equals(other.Configuration)) { return(false); } foreach (var g in one.Gateways) { GatewayEntry othergateway; if (!other.Gateways.TryGetValue(g.Key, out othergateway)) { return(false); } if (!g.Value.Equals(othergateway)) { return(false); } } return(true); }
public MultiClusterData ApplyDataAndNotify(MultiClusterData data) { if (data.IsEmpty) return data; MultiClusterData delta; MultiClusterData prev = this.localData; this.localData = prev.Merge(data, out delta); if (logger.IsVerbose2) logger.Verbose2("ApplyDataAndNotify: delta {0}", delta); if (delta.IsEmpty) return delta; if (delta.Configuration != null) { // notify configuration listeners of change // code will be added in separate PR } return delta; }
internal MultiClusterOracleData(Logger log) { logger = log; localData = new MultiClusterData(); activeGatewaysByCluster = new Dictionary<string, List<SiloAddress>>(); }
internal MultiClusterOracleData(TraceLogger log) { logger = log; localData = new MultiClusterData(); }
private void AssertEffect(MultiClusterData what, MultiClusterData to, MultiClusterData expectedMerge, MultiClusterData expectedDelta = null) { MultiClusterData delta; var merge = to.Merge(what, out delta); Assert.True(CheckEquality(expectedMerge, merge)); if (expectedDelta != null) Assert.Equal(expectedDelta, expectedDelta); }
public void MultiClusterData_Gateways() { var ts1 = DateTime.UtcNow; var ts2 = ts1 + new TimeSpan(hours: 0, minutes: 0, seconds: 1); var ts3 = ts1 + new TimeSpan(hours: 0, minutes: 0, seconds: 2); IPAddress ip; Assert.True(IPAddress.TryParse("127.0.0.1", out ip)); IPEndPoint ep1 = new IPEndPoint(ip, 21111); var siloAddress1 = SiloAddress.New(ep1, 0); IPEndPoint ep2 = new IPEndPoint(ip, 21112); var siloAddress2 = SiloAddress.New(ep2, 0); var G1 = new GatewayEntry() { SiloAddress = siloAddress1, ClusterId = "1", HeartbeatTimestamp = ts1, Status = GatewayStatus.Active }; var G2 = new GatewayEntry() { SiloAddress = siloAddress1, ClusterId = "1", HeartbeatTimestamp = ts3, Status = GatewayStatus.Inactive }; var H1 = new GatewayEntry() { SiloAddress = siloAddress2, ClusterId = "2", HeartbeatTimestamp = ts2, Status = GatewayStatus.Active }; var H2 = new GatewayEntry() { SiloAddress = siloAddress2, ClusterId = "2", HeartbeatTimestamp = ts3, Status = GatewayStatus.Inactive }; var gd1 = new MultiClusterData(); var gd2 = new MultiClusterData(G1); var gd3 = new MultiClusterData(G2); TestAlgebraicProperties(gd1, gd1); TestAlgebraicProperties(gd2, gd2); TestAlgebraicProperties(gd1, gd2); TestAlgebraicProperties(gd3, gd1); TestAlgebraicProperties(gd2, gd3); TestAlgebraicProperties(gd3, gd2); gd1 = new MultiClusterData(new GatewayEntry[] { H1, G2 }); gd2 = new MultiClusterData(new GatewayEntry[] { H2, G1 }); TestAlgebraicProperties(gd1, gd1); TestAlgebraicProperties(gd1, gd2); TestAlgebraicProperties(gd2, gd1); gd1 = new MultiClusterData(new GatewayEntry[] { H1, G2 }); gd2 = new MultiClusterData(new GatewayEntry[] { }); TestAlgebraicProperties(gd1, gd2); TestAlgebraicProperties(gd2, gd1); gd1 = new MultiClusterData(new GatewayEntry[] { H1, G2 }); gd2 = new MultiClusterData(new GatewayEntry[] { H1, G1 }); TestAlgebraicProperties(gd1, gd2); TestAlgebraicProperties(gd2, gd1); gd1 = new MultiClusterData(new GatewayEntry[] { H1, G2 }); gd2 = new MultiClusterData(new GatewayEntry[] { G1 }); TestAlgebraicProperties(gd1, gd2); TestAlgebraicProperties(gd2, gd1); gd1 = new MultiClusterData(new GatewayEntry[] { H1, G2 }); gd2 = new MultiClusterData(new GatewayEntry[] { H2 }); TestAlgebraicProperties(gd1, gd2); TestAlgebraicProperties(gd2, gd1); }
private bool CheckEquality(MultiClusterData one, MultiClusterData other) { if (one == null) return (other == null); if (other == null) return false; if ((one.Configuration == null) != (other.Configuration == null)) return false; if (one.Gateways.Count != other.Gateways.Count) return false; if ((one.Configuration != null) && !one.Configuration.Equals(other.Configuration)) return false; foreach (var g in one.Gateways) { GatewayEntry othergateway; if (!other.Gateways.TryGetValue(g.Key, out othergateway)) return false; if (!g.Value.Equals(othergateway)) return false; } return true; }
internal MultiClusterOracleData(Logger log) { logger = log; localData = new MultiClusterData(); }