/** * @param e Edge to close * @param cm message to send to other node * This method is used if we want to use a particular CloseMessage * If not, we can use the method with the same name with one fewer * parameters */ public void GracefullyClose(Edge e, string message) { /** * Close any connection on this edge, and * put the edge into the list of unconnected edges */ _connection_table.Disconnect(e); ListDictionary close_info = new ListDictionary(); string reason = message; if (reason != String.Empty) { close_info["reason"] = reason; } ProtocolLog.WriteIf(ProtocolLog.EdgeClose, String.Format( "GracefulCLose - " + e + ": " + reason)); var results = new BCon.Channel(1); EventHandler close_eh = delegate(object o, EventArgs args) { e.Close(); }; results.CloseEvent += close_eh; try { _rpc.Invoke(e, results, "sys:link.Close", close_info); } catch { Close(e); } }
/** * Handle the notification that the other side is going to close the edge */ public IDictionary Close(IDictionary close_message, ISender edge) { Edge from = GetEdge(edge); ConnectionTable tab = _node.ConnectionTable; /** * In order to make sure that we close gracefully, we simply * move this edge to the unconnected list. The node will * close edges that have been there for some time */ Connection c = tab.GetConnection(from); if (ProtocolLog.LinkDebug.Enabled) { ProtocolLog.Write(ProtocolLog.LinkDebug, String.Format( "sys:link.Close on {0} connection: {1}", from, c)); } tab.Disconnect(from); /** * Release locks when the close message arrives; do not wait * until the edge actually closes. */ CloseHandler(from, null); if (ProtocolLog.EdgeClose.Enabled) { String reason = String.Empty; if (close_message.Contains(reason)) { reason = (String)close_message["reason"]; } ProtocolLog.Write(ProtocolLog.EdgeClose, String.Format( "sys:link.Close - " + from + ": " + reason)); } /** * Try to close the edge after a small time span: */ Brunet.Util.FuzzyTimer.Instance.DoAfter(delegate(DateTime now) { _node.EnqueueAction(new Node.GracefulCloseAction(_node, from, "CPH, delayed close")); }, 5000, 1000); return(new ListDictionary()); }