//------------------------------------------------------------------------------------------------------------------------ private void NodeDiscovery_OnVBMReceived(NodeKey BrotherNode, VirtualBlockEventMsg msg) { try { HandleIncomingVirtualBlockEventMsg(msg); } catch (Exception ex) { DebugEx.Assert(ex); } }
//------------------------------------------------------------------------------------------------------------------------ public void SendVBMToBrothers(List <VirtualBlockEvent> events) { try { //split into packets-per brother var brotherPackets = new Dictionary <NodeKey, List <VirtualBlockEvent> >(); foreach (var ev in events) { var bk = (BlockKey)ev.BlockKey; var nk = bk.GraphKey.NodeKey; if (BrotherNodes.ContainsKey(nk)) { //get (or create) packet list var packets = brotherPackets.TryGetOrDefault(nk); if (packets == null) { brotherPackets.Add(nk, packets = new List <VirtualBlockEvent>()); } //add packet for brother node packets.Add(ev); } } //send to brothers and consume foreach (var bpkv in brotherPackets) { //get brother var brother = BrotherNodes.TryGetOrDefault(bpkv.Key); if (brother != null && brother.IsConnected) { var msgReq = new VirtualBlockEventMsg() { BlockEvents = bpkv.Value.ToArray(), }; var rsp = brother.SendRequest <GenericRsp>(msgReq, Timeout: TimeSpan.FromSeconds(3)); if (rsp != null && rsp.IsSuccess) { //consume events from original set msgReq.BlockEvents.ForEach(e => events.Remove(e)); } } } } catch (Exception ex) { DebugEx.Assert(ex, "Unhandled exception in SendVBMToBrothers"); } }
//------------------------------------------------------------------------------------------------------------------------ public void HandleIncomingVirtualBlockEventMsg(VirtualBlockEventMsg msg) { lock (locker) { List <Yodiwo.Logic.GraphManager.SimultaneousActionRequest> simReq = null; //create a simultaneous action requests foreach (var ev in msg.BlockEvents) { var bk = (BlockKey)ev.BlockKey; if (bk.IsInvalid) { DebugEx.Assert("Invalid blockkey detected in received VirtualBlockEvent"); continue; } var _req = new Yodiwo.Logic.GraphManager.SimultaneousActionRequest() { BlockKey = bk, BlockActionData = new Logic.Blocks.Endpoints.Out.VirtualOutput.VirtualIOMsg() { RemoteVirtualInputBlockKey = bk, Indices = ev.Indices, Values = ev.Values, Revision = ev.RevNum, }, }; //add to simReq if (simReq == null) { simReq = new List <GraphManager.SimultaneousActionRequest>(); } simReq.Add(_req); } //send action request if (simReq != null && simReq.Count > 0) { GraphManager.RequestGraphAction(simReq); } } }
//------------------------------------------------------------------------------------------------------------------------ void VirtualOutputBatchMsgHandler(Logic.Blocks.Endpoints.Out.VirtualOutput.VirtualIOMsg[] ev) { try { //compile events var events = ev.Where(e => e.RemoteVirtualInputBlockKey.IsValid) .Select(e => new VirtualBlockEvent() { BlockKey = e.RemoteVirtualInputBlockKey, Indices = e.Indices, Values = e.Values.Select(v => v.ToJSON()).ToArray(), RevNum = e.Revision, }) .ToList(); if (events.Count == 0) { return; } //redirect vbm to a brothernode? if (Node.NodeDiscovery != null) { //send to events to local brother nodes (set will be consumed up to a point) Node.NodeDiscovery.SendVBMToBrothers(events); //if nothing left then done! if (events.Count == 0) { return; } } //send virtual block event msg var msg = new VirtualBlockEventMsg() { BlockEvents = events.ToArray(), }; Node.SendMessage(msg); } catch (Exception ex) { DebugEx.Assert(ex, "Unhandled exception caught"); } }
//------------------------------------------------------------------------------------------------------------------------ public void SendVBMToBrothers(List<VirtualBlockEvent> events) { try { //split into packets-per brother var brotherPackets = new Dictionary<NodeKey, List<VirtualBlockEvent>>(); foreach (var ev in events) { var bk = (BlockKey)ev.BlockKey; var nk = bk.GraphKey.NodeKey; if (BrotherNodes.ContainsKey(nk)) { //get (or create) packet list var packets = brotherPackets.TryGetOrDefault(nk); if (packets == null) brotherPackets.Add(nk, packets = new List<VirtualBlockEvent>()); //add packet for brother node packets.Add(ev); } } //send to brothers and consume foreach (var bpkv in brotherPackets) { //get brother var brother = BrotherNodes.TryGetOrDefault(bpkv.Key); if (brother != null && brother.IsConnected) { var msgReq = new VirtualBlockEventMsg() { BlockEvents = bpkv.Value.ToArray(), }; var rsp = brother.SendRequest<GenericRsp>(msgReq, Timeout: TimeSpan.FromSeconds(3)); if (rsp != null && rsp.IsSuccess) { //consume events from original set msgReq.BlockEvents.ForEach(e => events.Remove(e)); } } } } catch (Exception ex) { DebugEx.Assert(ex, "Unhandled exception in SendVBMToBrothers"); } }
//------------------------------------------------------------------------------------------------------------------------ private void RemoteNode_OnVBMReceived(RemoteNode RemoteNode, VirtualBlockEventMsg msg) { OnVBMReceived?.Invoke(RemoteNode.RemoteNodeKey, msg); }
//------------------------------------------------------------------------------------------------------------------------ public void HandleIncomingVirtualBlockEventMsg(VirtualBlockEventMsg msg) { lock (locker) { List<Yodiwo.Logic.GraphManager.SimultaneousActionRequest> simReq = null; //create a simultaneous action requests foreach (var ev in msg.BlockEvents) { var bk = (BlockKey)ev.BlockKey; if (bk.IsInvalid) { DebugEx.Assert("Invalid blockkey detected in received VirtualBlockEvent"); continue; } var _req = new Yodiwo.Logic.GraphManager.SimultaneousActionRequest() { BlockKey = bk, BlockActionData = new Logic.Blocks.Endpoints.Out.VirtualOutput.VirtualIOMsg() { RemoteVirtualInputBlockKey = bk, Indices = ev.Indices, Values = ev.Values, Revision = ev.RevNum, }, }; //add to simReq if (simReq == null) simReq = new List<GraphManager.SimultaneousActionRequest>(); simReq.Add(_req); } //send action request if (simReq != null && simReq.Count > 0) GraphManager.RequestGraphAction(simReq); } }
//------------------------------------------------------------------------------------------------------------------------ void VirtualOutputBatchMsgHandler(Logic.Blocks.Endpoints.Out.VirtualOutput.VirtualIOMsg[] ev) { try { //compile events var events = ev.Where(e => e.RemoteVirtualInputBlockKey.IsValid) .Select(e => new VirtualBlockEvent() { BlockKey = e.RemoteVirtualInputBlockKey, Indices = e.Indices, Values = e.Values.Select(v => v.ToJSON()).ToArray(), RevNum = e.Revision, }) .ToList(); if (events.Count == 0) return; //redirect vbm to a brothernode? if (Node.NodeDiscovery != null) { //send to events to local brother nodes (set will be consumed up to a point) Node.NodeDiscovery.SendVBMToBrothers(events); //if nothing left then done! if (events.Count == 0) return; } //send virtual block event msg var msg = new VirtualBlockEventMsg() { BlockEvents = events.ToArray(), }; Node.SendMessage(msg); } catch (Exception ex) { DebugEx.Assert(ex, "Unhandled exception caught"); } }