public void TestSyn() { const string node1Endpoint = "192.168.1.1:18841"; const string node2Endpoint = "192.168.1.2:18841"; var node1 = CreateNode(node1Endpoint, new[] { node2Endpoint }.Concat(SeedsEndpoint)); var node2 = CreateNode(node2Endpoint, new[] { node1Endpoint }.Concat(SeedsEndpoint)); var synRequest = new Ping1Request(); synRequest.NodesSynopsis.AddRange(node1.GetNodesSynposis()); var synResponse = node2.Syn(synRequest); Assert.Equal( new NodeInformationSynopsis { Endpoint = node1.EndPoint, LastKnownPropertyVersion = 0, NodeVersion = 0 }, synResponse.RequiredNodesSynopsis.Single()); Assert.Equal( node2.nodeInformationDictionary[node2.EndPoint], synResponse.UpdatedNodes.Single()); }
public Ping1Response Syn(Ping1Request syn) { lock (lockObject) { var response = new Ping1Response(); FillRequiredOrUpdatedNodes( syn.NodesSynopsis, response.RequiredNodesSynopsis, response.UpdatedNodes); return(response); } }
public void PrintMessageSizeForClusterSize() { var node = CreateNode(SelfEndpoint, SeedsEndpoint); var baseIpAddress = IPAddress.Parse("192.168.1.1"); for (int i = 0; i < 10000; i++) { #pragma warning disable CS0618 baseIpAddress.Address++; #pragma warning restore CS0618 var endpoint = baseIpAddress.ToString() + ":19999"; node.nodeInformationDictionary.Add( endpoint, NodeInformation.CreateSelfNode(endpoint)); } var ping1Request = new Ping1Request { NodesSynopsis = { node.GetNodesSynposis() } }; logger.LogInformation("Ping1 request size: {0}", ping1Request.CalculateSize()); }
public override Task <Ping1Response> Ping1(Ping1Request request, ServerCallContext context) { return(Task.FromResult(node.Syn(request))); }
public void TestFullSyncBasic() { const string node1Endpoint = "192.168.1.1:18841"; const string node2Endpoint = "192.168.1.2:18841"; var node1 = CreateNode(node1Endpoint, new[] { node2Endpoint }.Concat(SeedsEndpoint)); var node2 = CreateNode(node2Endpoint, new[] { node1Endpoint }.Concat(SeedsEndpoint)); var synRequest = new Ping1Request(); synRequest.NodesSynopsis.AddRange(node1.GetNodesSynposis()); var synResponse = node2.Syn(synRequest); var ack2Request = node1.Ack1(synResponse); var ack2Response = node2.Ack2(ack2Request); Assert.Equal(new Ping2Response(), ack2Response); Assert.Equal( new NodeInformation { Endpoint = node1Endpoint, NodeStateProperty = new VersionedProperty { StateProperty = NodeState.Live, Version = 2 }, NodeVersion = GetNodeVersion(), }, node1.nodeInformationDictionary[node1Endpoint]); Assert.Equal( new NodeInformation { Endpoint = node2Endpoint, NodeStateProperty = new VersionedProperty { StateProperty = NodeState.Live, Version = 2 }, NodeVersion = GetNodeVersion(), }, node1.nodeInformationDictionary[node2Endpoint]); foreach (var e in SeedsEndpoint) { Assert.Equal( NodeInformation.CreateSeedNode(e), node1.nodeInformationDictionary[e]); } Assert.Equal( new NodeInformation { Endpoint = node1Endpoint, NodeStateProperty = new VersionedProperty { StateProperty = NodeState.Live, Version = 2 }, NodeVersion = GetNodeVersion(), }, node2.nodeInformationDictionary[node1Endpoint]); Assert.Equal( new NodeInformation { Endpoint = node2Endpoint, NodeStateProperty = new VersionedProperty { StateProperty = NodeState.Live, Version = 2 }, NodeVersion = GetNodeVersion(), }, node2.nodeInformationDictionary[node2Endpoint]); foreach (var e in SeedsEndpoint) { Assert.Equal( NodeInformation.CreateSeedNode(e), node2.nodeInformationDictionary[e]); } }
private async Task SyncWithPeerAsync(string peerEndpoint, Random random, CancellationToken cancellationToken) { var client = clientFactory.Invoke(peerEndpoint); var options = optionsMonitor.CurrentValue; var synRequest = new Ping1Request(); synRequest.NodesSynopsis.AddRange(node.GetNodesSynposis()); bool failed = false; try { var synResponse = await client.Ping1Async( synRequest, deadline : DateTime.UtcNow + TimeSpan.FromMilliseconds(options.PingTimeoutMilliseconds), cancellationToken : cancellationToken); var ack2Request = node.Ack1(synResponse); var ack2Response = await client.Ping2Async( ack2Request, deadline : DateTime.UtcNow + TimeSpan.FromMilliseconds(options.PingTimeoutMilliseconds), cancellationToken : cancellationToken); } catch (GrpcException ex) { logger.LogError(ex, "Cannot ping peer {0} because {1}", peerEndpoint, ex.Message); failed = true; } if (failed) { // TODO: pick k nodes & forward ping concurrently, currently only implement k = 1 var forwarderEndpoint = RandomPickNode(random, node.LiveEndpoints, new List <string>()); if (forwarderEndpoint == null) { throw new InvalidOperationException("Cannot pick a node for forwarder"); } logger.LogInformation("Pick peer {0} as forwarder to connect peer {1}", forwarderEndpoint, peerEndpoint); client = clientFactory.Invoke(forwarderEndpoint); var forwardedSynResponse = await client.ForwardAsync( new ForwardRequest { TargetEndpoint = peerEndpoint, TargetMethod = nameof(client.Ping1), Ping1Request = synRequest }, deadline : DateTime.UtcNow + TimeSpan.FromMilliseconds(options.ForwardTimeoutMilliseconds), cancellationToken : cancellationToken); Ping1Response synResponse; switch (forwardedSynResponse.ResponseCase) { case ForwardResponse.ResponseOneofCase.ErrorMessage: throw new RpcRemoteException(forwardedSynResponse.ErrorMessage); case ForwardResponse.ResponseOneofCase.None: throw new RpcInvalidResponseException("Forward response not set content from remote"); case ForwardResponse.ResponseOneofCase.Ping1Response: synResponse = forwardedSynResponse.Ping1Response; break; default: throw new RpcInvalidResponseException("Unknown response type"); } var ack2Request = node.Ack1(synResponse); var forwardedAck2Response = await client.ForwardAsync( new ForwardRequest { TargetEndpoint = peerEndpoint, TargetMethod = nameof(client.Ping2), Ping2Request = ack2Request }, deadline : DateTime.UtcNow + TimeSpan.FromMilliseconds(options.ForwardTimeoutMilliseconds), cancellationToken : cancellationToken); Ping2Response ack2Response; switch (forwardedAck2Response.ResponseCase) { case ForwardResponse.ResponseOneofCase.ErrorMessage: throw new RpcRemoteException(forwardedSynResponse.ErrorMessage); case ForwardResponse.ResponseOneofCase.None: throw new RpcInvalidResponseException("Forward response not set content from remote"); case ForwardResponse.ResponseOneofCase.Ping2Response: ack2Response = forwardedAck2Response.Ping2Response; break; default: throw new RpcInvalidResponseException("Unknown response type"); } } }