private void HandleCallReq(PyPacket packet, Client client) { PyTuple callInfo = ((packet.Payload[0] as PyTuple)[1] as PySubStream).Stream as PyTuple; string call = callInfo[1] as PyString; PyTuple args = callInfo[2] as PyTuple; PyDictionary sub = callInfo[3] as PyDictionary; PyDataType callResult = null; PyAddressClient source = packet.Source as PyAddressClient; string destinationService = null; CallInformation callInformation; if (packet.Destination is PyAddressAny destAny) { destinationService = destAny.Service; } else if (packet.Destination is PyAddressNode destNode) { destinationService = destNode.Service; if (destNode.NodeID != Container.NodeID) { Log.Fatal( "Received a call request for a node that is not us, did the ClusterController get confused or something?!" ); return; } } callInformation = new CallInformation { Client = client, CallID = source.CallID, NamedPayload = sub, PacketType = packet.Type, Service = destinationService, From = packet.Source, To = packet.Destination }; try { if (destinationService == null) { if (callInfo[0] is PyString == false) { Log.Fatal("Expected bound call with bound string, but got something different"); return; } string boundString = callInfo[0] as PyString; // parse the bound string to get back proper node and bound ids Match regexMatch = Regex.Match(boundString, "N=([0-9]+):([0-9]+)"); if (regexMatch.Groups.Count != 3) { Log.Fatal($"Cannot find nodeID and boundID in the boundString {boundString}"); return; } int nodeID = int.Parse(regexMatch.Groups[1].Value); int boundID = int.Parse(regexMatch.Groups[2].Value); if (nodeID != this.Container.NodeID) { Log.Fatal("Got bound service call for a different node"); // TODO: MIGHT BE A GOOD IDEA TO RELAY THIS CALL TO THE CORRECT NODE // TODO: INSIDE THE NETWORK, AT LEAST THAT'S WHAT CCP IS DOING BASED // TODO: ON THE CLIENT'S CODE... NEEDS MORE INVESTIGATION return; } #if DEBUG CallLog.Trace("Payload"); CallLog.Trace(PrettyPrinter.FromDataType(args)); CallLog.Trace("Named payload"); CallLog.Trace(PrettyPrinter.FromDataType(sub)); #endif callResult = this.BoundServiceManager.ServiceCall( boundID, call, args, callInformation ); #if DEBUG ResultLog.Trace("Result"); ResultLog.Trace(PrettyPrinter.FromDataType(callResult)); #endif } else { Log.Trace($"Calling {destinationService}::{call}"); #if DEBUG CallLog.Trace("Payload"); CallLog.Trace(PrettyPrinter.FromDataType(args)); CallLog.Trace("Named payload"); CallLog.Trace(PrettyPrinter.FromDataType(sub)); #endif callResult = this.ServiceManager.ServiceCall( destinationService, call, args, callInformation ); #if DEBUG ResultLog.Trace("Result"); ResultLog.Trace(PrettyPrinter.FromDataType(callResult)); #endif } this.SendCallResult(callInformation, callResult); } catch (PyException e) { this.SendException(callInformation, e); } catch (ProvisionalResponse provisional) { this.SendProvisionalResponse(callInformation, provisional); } }