/// <summary> /// AddTupleToBeAcked inserts tuple in ToBeAcked. /// </summary> /// <param name="t">Tuple that will be acked</param> public void AddTupleToBeAcked(Tuple t, string ackUrl)//Add tuple t to be acked { if (!RepInfo.Semantics.Equals("at-most-once")) { AckTuple temp = new AckTuple(t, ackUrl); ToBeAcked.Add(temp); } }
public void removeToBeAck(AckTuple t)//Remove tuple that needed to be sent ack from the list { if (!RepInfo.Semantics.Equals("at-most-once")) { if (ToBeAcked.Contains(t)) { Console.WriteLine("removeToBeAck: " + t.AckT.toString()); ToBeAcked.Remove(t); } else { Console.WriteLine("removeToBeAck: Error while removing tuple after being acked: " + t.AckT.toString()); } } }
/// <summary> /// Method to call the right operation on the tuple received. /// </summary> /// <param name="t">Tuple to be processed.</param> public IList <Tuple> processTuple(Tuple t) { processTuple value; bool notInList = true;//is it needed to update the TupleToTupleProcessed array IList <Tuple> result = new List <Tuple>(); if (RepInfo.Semantics.Equals("exactly-once")) { Console.WriteLine("Tuple: " + t.toString() + " id: " + t.Id); foreach (Tuple2TupleProcessed t2t in TupleToTupleProcessed.ToArray()) //List of tuples already processed { if (t2t != null && t.Id.Equals(t2t.Pre.Id)) //Checking if the new processing tuple was already processed { if (Comments) { Console.WriteLine("Tuple already processed going to reject it"); } result = null;//rejects duplicated tuples notInList = false; } } if (notInList) { processors.TryGetValue(this.repInfo.Operator_spec, out value); //getting the processor method for this operator result = value(t); //Processing the tuple Tuple2TupleProcessed temp = new Tuple2TupleProcessed(t, result); TupleToTupleProcessed.Add(temp); foreach (string url in RepInfo.SiblingsUrls.ToArray())//in this semantics (exactly-once) the sibling tuples receive a copy of the already processed tuples { if (url != null && !url.Equals(RepInfo.MyUrl)) { try { OperatorServices obj = (OperatorServices)Activator.GetObject(typeof(OperatorServices), url); obj.addTupleToTupleProcessed(temp); Console.WriteLine("TupleToTupleProcessed added: " + t.toString() + " to the sibling: " + url); } catch (System.Net.Sockets.SocketException e) {//if the other replica is dead there is no problem in not having it receiving the copy of the already processed Tuples aka TupleToTupleProcessed } } } } } else { processors.TryGetValue(this.repInfo.Operator_spec, out value); //getting the processor method for this operator result = value(t); //Processing the tuple } //Give ack to previous rep foreach (AckTuple t2 in ToBeAcked.ToArray()) { if (t2 != null && t2.AckT.Id.Equals(t.Id)) { Console.WriteLine("Going to remove the tuple from to be acked list : " + t.toString()); ackTuple(t); this.removeToBeAck(t2); break; } } if (!RepInfo.Semantics.Equals("at-most-once")) { foreach (string url in RepInfo.SiblingsUrls.ToArray())//Sharing with this rep siblings the tuples that need to receive ack in order to allow fault tolerance { if (url != null && !url.Equals(RepInfo.MyUrl)) { try { OperatorServices obj = (OperatorServices)Activator.GetObject(typeof(OperatorServices), url); obj.addRepTuple(t); Console.WriteLine("Added tuple: " + t.toString() + " to the sibling in: " + url); } catch (System.Net.Sockets.SocketException e) {//If the other replicas is dead there is no problem in not having it receiving the copy of the tuples that need to be processed in case of failure of the "main" replica } } } } return(result); }