/// <summary> /// Sends tuples to the next Operator in the channel. /// </summary> /// <param name="t">Tuple to be sent.</param> public void SendTuple(Tuple t, bool resend) { bool last = true; ArrayList urls; foreach (string opx in OpsIds.ToArray()) { if (opx != null) { repInfo.SendInfoUrls.TryGetValue(opx, out urls); if (urls.Count >= 1) { last = false; sendTuplePolicy value;//Delegate that will use the policy of the replica to calculate the outgoing replica for this tuple t policies.TryGetValue(this.repInfo.Next_routing, out value); //Getting the OperatorServices object try { OperatorServices obj = (OperatorServices)Activator.GetObject(typeof(OperatorServices), value(urls, t)); if (Comments) { obj.ping("PING!"); } if (!resend && !RepInfo.Semantics.Equals("at-most-once")) { AddTupleToReceiveAck(t, resend); //Save tuple to receive ack stating if it is a resend or not foreach (string url2 in RepInfo.SiblingsUrls.ToArray()) //share the acks that need to be received with its siblings { if (url2 != null && !url2.Equals(RepInfo.MyUrl)) { OperatorServices obj2 = (OperatorServices)Activator.GetObject(typeof(OperatorServices), url2); obj2.AddTupleToReceiveAck(t, resend); Console.WriteLine("Added receive ack of tuple: " + t.toString() + " to the sibling: " + url2); } } } if (!RepInfo.Semantics.Equals("at-most-once")) { obj.AddTupleToBeAcked(t, RepInfo.MyUrl);//Added tuple to be acked in the receiving replica } obj.AddTupleToBuffer(t); } catch (System.Net.Sockets.SocketException e) {// if the other replica rejects the connection the tuple is not send and the timer will make this replica resend the tuple to one of the possible sending replicas } } } } if (last) { if (comments) { Console.WriteLine("I am one of the last operator's replica"); } return; } }