public void HandleRpc(ISender caller, string meth, IList args, object state) { if (meth == "create") { Edge calling_edge = (Edge)((ReqrepManager.ReplyState)caller).ReturnPath; string remote_path = (string)args[0]; string local_path = (string)args[1]; PathEdgeListener el = _pel_map[local_path]; if (el.IsStarted) { PathEdge npe = new PathEdge(calling_edge, local_path, remote_path); lock ( _sync ) { //We don't announce yet, wait till we get some data, which //verifies that the other side has seen it. _unannounced[calling_edge] = npe; } //So the new Edge has been announced. Rpc.SendResult(state, true); } else { throw new Exception( String.Format("PathEdgeListener({0}) not started", local_path)); } } else { throw new AdrException(-32601, "No Handler for method: " + meth); } }
/** * Handles Rrm TimeoutChecking as well as removing stale entries from the * _unannounced Edge dictionary. */ protected void TimeoutCheck() { _rrm.TimeoutChecker(null, null); DateTime now = DateTime.UtcNow; long next = _next_check; if (next < now.Ticks) { // If someone else is checking it, let's just end it here long current = Interlocked.Exchange(ref _next_check, now.AddMinutes(5).Ticks); if (next != current) { return; } } // Get the list of old edges DateTime remove_timeout = now.AddMinutes(-5); List <Edge> to_close = new List <Edge>(); lock (_sync) { foreach (Edge e in _unannounced.Keys) { if (e.CreatedDateTime < remove_timeout) { to_close.Add(e); } } } // Close the Edges foreach (Edge e in to_close) { PathEdge pe = null; if (!_unannounced.TryGetValue(e, out pe)) { continue; } try { pe.Close(); } catch (Exception ex) { Console.WriteLine(ex); } } // Remove them from the _unannounced dictionary lock (_sync) { foreach (Edge e in to_close) { _unannounced.Remove(e); } } }
/** try to create a new PathEdge and send the EdgeEvent */ public void SendPathEdgeEvent(PathEdge pe) { if (1 == _is_started) { SendEdgeEvent(pe); } else { throw new Exception( String.Format("PathEdgeListener{0} not yet started", _path)); } }
public void HandleEC(bool succ, Edge e, Exception x) { if (succ) { /* * Got the underlying Edge, now do the path protocol */ Channel results = new Channel(1); results.CloseEvent += delegate(object q, EventArgs args) { try { RpcResult res = (RpcResult)results.Dequeue(); object o = res.Result; if (o is Exception) { Console.WriteLine(o); throw (o as Exception); } //If we get here, everything looks good: PathEdge pe = new PathEdge(e, LocalPath, RemotePath); //Start sending e's packets into pe pe.Subscribe(); ECB(true, pe, null); } catch (Exception cx) { ECB(false, null, cx); } }; //Make sure we hear the packets on this edge: e.Subscribe(_pel._pem, null); //Now make the rpc call: _pel._pem.Rpc.Invoke(e, results, "sys:pathing.create", LocalPath, RemotePath); } else { ECB(false, null, x); } }
/** Handle incoming data on an Edge */ public void HandleData(MemBlock data, ISender retpath, object state) { MemBlock rest_of_data; PType p; if (state == null) { p = PType.Parse(data, out rest_of_data); } else { //a demux has already happened: p = (PType)state; rest_of_data = data; } if (PType.Protocol.Pathing.Equals(p)) { /* * We use a special PType to denote this transaction so * we don't confuse it with other RepRep communication */ _rrm.HandleData(rest_of_data, retpath, null); } else if (PType.Protocol.Rpc.Equals(p)) { /* * Send this to the RpcHandler */ Rpc.HandleData(rest_of_data, retpath, null); } else { /* * This is some other data * It is either: * 1) Time to announce an already created edge. * 2) Assume this is a "default path" edge creation, to be backwards * compatible */ Edge e = null; PathEdge pe = null; try { e = (Edge)retpath; PathEdgeListener pel = null; lock ( _sync ) { if (_unannounced.TryGetValue(e, out pe)) { // _unannounced.Remove(e); pel = _pel_map[pe.LocalPath]; } } if (pe == null) { /* * This must be a "default path" incoming connection */ pel = _pel_map[Root]; pe = new PathEdge(e, Root, Root); } pel.SendPathEdgeEvent(pe); pe.Subscribe(); pe.ReceivedPacketEvent(data); } catch (Exception x) { if (pe != null) { //This closes both edges: pe.Close(); } else if (e != null) { Console.WriteLine("Closing ({0}) due to: {1}", e, x); e.Close(); } } } }