public async void TestGracefulHalt() { Peer sender = null; Peer recv1 = null; ChannelCreator cc = null; try { sender = new PeerBuilder(new Number160("0x9876")) .SetChannelServerConfiguration(Utils2.CreateInfiniteTimeoutChannelServerConfiguration(2424, 2424)) .SetMaintenanceTask(Utils2.CreateInfiniteIntervalMaintenanceTask()) .SetP2PId(55) .SetPorts(2424) .Start(); recv1 = new PeerBuilder(new Number160("0x1234")) .SetChannelServerConfiguration(Utils2.CreateInfiniteTimeoutChannelServerConfiguration(7777, 7777)) .SetMaintenanceTask(Utils2.CreateInfiniteIntervalMaintenanceTask()) .SetP2PId(55) .SetPorts(7777) .Start(); // bootstrap first await sender.Bootstrap().SetPeerAddress(recv1.PeerAddress).StartAsync(); Assert.IsTrue(sender.PeerBean.PeerMap.All.Count == 1); Assert.IsTrue(recv1.PeerBean.PeerMap.AllOverflow.Count == 1); // graceful shutdown cc = await recv1.ConnectionBean.Reservation.CreateAsync(1, 0); var shutdownBuilder = new ShutdownBuilder(sender); await sender.QuitRpc.QuitAsync(recv1.PeerAddress, shutdownBuilder, cc); await sender.ShutdownAsync(); sender = null; // ignore finally-block shutdown Assert.IsTrue(recv1.PeerBean.PeerMap.All.Count == 0); } finally { if (cc != null) { cc.ShutdownAsync().Wait(); } if (sender != null) { sender.ShutdownAsync().Wait(); } if (recv1 != null) { recv1.ShutdownAsync().Wait(); } } }
/// <summary> /// Sends a message that indicates this peer is about to quit. This is an RPC. /// </summary> /// <param name="remotePeer">The remote peer to send this request.</param> /// <param name="shutdownBuilder">Used for the sign and force TCP flag. Set if the message should be signed.</param> /// <param name="channelCreator">The channel creator that creates connections.</param> /// <returns>The future response message.</returns> public Task<Message.Message> QuitAsync(PeerAddress remotePeer, ShutdownBuilder shutdownBuilder, ChannelCreator channelCreator) { var message = CreateRequestMessage(remotePeer, Rpc.Commands.Quit.GetNr(), Message.Message.MessageType.RequestFf1); if (shutdownBuilder.IsSign) { message.SetPublicKeyAndSign(shutdownBuilder.KeyPair); } var tcsResponse = new TaskCompletionSource<Message.Message>(message); var requestHandler = new RequestHandler(tcsResponse, PeerBean, ConnectionBean, shutdownBuilder); Logger.Debug("Send QUIT message {0}.", message); if (!shutdownBuilder.IsForceTcp) { return requestHandler.FireAndForgetUdpAsync(channelCreator); } return requestHandler.SendTcpAsync(channelCreator); }
/// <summary> /// Sends a message that indicates this peer is about to quit. This is an RPC. /// </summary> /// <param name="remotePeer">The remote peer to send this request.</param> /// <param name="shutdownBuilder">Used for the sign and force TCP flag. Set if the message should be signed.</param> /// <param name="channelCreator">The channel creator that creates connections.</param> /// <returns>The future response message.</returns> public Task <Message.Message> QuitAsync(PeerAddress remotePeer, ShutdownBuilder shutdownBuilder, ChannelCreator channelCreator) { var message = CreateRequestMessage(remotePeer, Rpc.Commands.Quit.GetNr(), Message.Message.MessageType.RequestFf1); if (shutdownBuilder.IsSign) { message.SetPublicKeyAndSign(shutdownBuilder.KeyPair); } var tcsResponse = new TaskCompletionSource <Message.Message>(message); var requestHandler = new RequestHandler(tcsResponse, PeerBean, ConnectionBean, shutdownBuilder); Logger.Debug("Send QUIT message {0}.", message); if (!shutdownBuilder.IsForceTcp) { return(requestHandler.FireAndForgetUdpAsync(channelCreator)); } return(requestHandler.SendTcpAsync(channelCreator)); }