public void ackTuple(Tuple t)//AckTuples if needed { if (!RepInfo.Semantics.Equals("at-most-once")) { Console.WriteLine("TupleAcked: " + t.toString()); foreach (string url in RepInfo.ReceiveInfoUrls.ToArray())//Acking tuples to the previous op, if at least one receives the ack the tuple is acked and propagated { try { if (url != null) { OperatorServices obj = (OperatorServices)Activator.GetObject(typeof(OperatorServices), url); obj.receivedAck(t, true); if (comments) { Console.WriteLine("At least one replica received the ack"); } break; } } catch (System.Net.Sockets.SocketException e)//It is only needed to receive at least one ack per operator i.e just one replica of an operator needs to receive the ack { continue; } } } }
/// <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; } }
/// <summary> /// ThrPool constructor. /// </summary> /// <param name="thrNum">Number of threads to be created.</param> /// <param name="size">Size of the circular buffers.</param> /// <param name="operatorService">Operator that owns the Thread Pool.</param> public ThrPool(int thrNum, int bufSize, OperatorServices operatorService) { //Initialize attributes bufferRead = new CircularBuffer <Tuple>(bufSize); bufferProcessed = new CircularBuffer <Tuple>(bufSize); pool = new Thread[thrNum]; this.operatorService = operatorService; tuplesRead = new List <Tuple>(); //Start threads int i = 0; pool[i] = new Thread(new ThreadStart(ConsumeRead)); pool[i++].Start(); pool[i] = new Thread(new ThreadStart(ConsumeProcessed)); pool[i++].Start(); }
/// <summary> /// Main publishes OperatorServices at a certain url /// </summary> /// <param name="args">Port where the service will be published.</param> static void Main(string[] args) { int port = Int32.Parse(args[0]); string opName = args[1]; //Creating the channel TcpChannel serverChannel = new TcpChannel(port); ChannelServices.RegisterChannel(serverChannel, false); // Expose an object form RepServices for remote calls. opServices = new OperatorServices(); RemotingServices.Marshal(opServices, opName, typeof(OperatorServices)); Console.WriteLine("I am an op replica and I am located at the port: " + port); System.Console.WriteLine("Press <enter> to terminate server..."); System.Console.ReadLine(); }
public void receivedAck(Tuple t, bool notRep)//Remove tuple that needed to receive ack from the list { if (!RepInfo.Semantics.Equals("at-most-once")) { foreach (Tuple t2 in ToReceiveAck.ToArray()) { if (t2 != null && t.Id.Equals(t2.Id)) { ToReceiveAck.Remove(t); removeRepTuple(t);//removes if exists the replica of a a tuple processed foreach (TimerTuple t3 in TimerAck.ToArray()) { if (t3 != null && t.Id.Equals(t3.AckT.Id)) { t3.Time.Dispose(); TimerAck.Remove(t3); Console.WriteLine("receivedAck: " + t.toString()); break; } } if (notRep) { foreach (string url in RepInfo.SiblingsUrls.ToArray())//removes replicated receive acks from siblings { if (url != null && !url.Equals(RepInfo.MyUrl)) { try { OperatorServices obj = (OperatorServices)Activator.GetObject(typeof(OperatorServices), url); obj.receivedAck(t, false); Console.WriteLine("Removed ack of tuple: " + t.toString() + " from sibling: " + url); } catch (System.Net.Sockets.SocketException e) {//if the replica that should received ack is dead no problem } } } } return;//We only want to remove 1 } } Console.WriteLine("receivedAck: Error while removing tuple after being acked: " + t.toString()); } }
public static void sendAliveParents(OperatorServices me) { if (!(me.RepFreeze && me.RepCrash)) { foreach (string url in me.ChildrensUrl.ToArray()) { try { if (url != null) { OperatorServices obj = (OperatorServices)Activator.GetObject(typeof(OperatorServices), url); String ping = obj.getPing(); } } catch (System.Net.Sockets.SocketException e)//if a children of a replica dies happens the following { me.ChildrensUrl.Remove(url); ArrayList temp; ArrayList renewList = new ArrayList(); string renewOpx = ""; foreach (string opx in me.OpsIds.ToArray()) { if (opx != null) { me.RepInfo.SendInfoUrls.TryGetValue(opx, out temp); foreach (string s in temp.ToArray()) { if (s != null && s.Equals(url)) { temp.Remove(url); renewList = temp; renewOpx = opx; break; } } } } me.RepInfo.SendInfoUrls[renewOpx] = renewList;//Updating the dictionary of replicas } } } }
public static void sendAliveSiblings(OperatorServices me) { if (!(me.RepFreeze && me.RepCrash)) { foreach (string url in me.RepInfo.SiblingsUrls.ToArray()) { if (url != null && !url.Equals(me.RepInfo.MyUrl)) { try { OperatorServices obj = (OperatorServices)Activator.GetObject(typeof(OperatorServices), url); String ping = obj.getPing(); } catch (System.Net.Sockets.SocketException e)//If a sibling of a replica dies happens the following { me.RepInfo.SiblingsUrls.Remove(url); me.RecoverySend(me.ReplicatedTuples); } } } } }
/// <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); }
/// <summary> /// ConsumeRead gets tuple from bufferRead and processes it. /// </summary> public void ConsumeRead() { while (true) { while (operatorService.RepStatus.Equals("Unitialized")) { } //Get tuple from bufferRead Tuple t = bufferRead.Consume(); string log; if (operatorService.Comments) { Console.WriteLine("Consumed tuple " + t.toString() + " from buffer of Read Tuples"); } //Processing tuple IList <Tuple> tuplesToProcess = operatorService.processTuple(t); if (tuplesToProcess != null) { foreach (Tuple tuple in tuplesToProcess) { //Mark tuple as read tuplesRead.Add(tuple); if (!operatorService.RepInfo.Semantics.Equals("at-most-once")) {//If the routing of this replica is primary we want to share the readtuples array //in order to have consistency while counting or check if a tuple is unique if (operatorService.RepInfo.Routing.Equals("primary")) { foreach (string url in operatorService.RepInfo.SiblingsUrls.ToArray()) { if (url != null && !url.Equals(operatorService.RepInfo.MyUrl)) { try { OperatorServices obj = (OperatorServices)Activator.GetObject(typeof(OperatorServices), url); obj.addTupleRead(tuple); } catch (System.Net.Sockets.SocketException e) {// if the other replica rejects the connection the tuple is not send to the sibling but there is no problem because it is dead } } } } } //Send log to PM bufferProcessed.Produce(tuple); Console.WriteLine("Processed tuple " + tuple.toString() + " and accepted."); log = tuple.toString(); operatorService.NotifyPM("Tuple replica_URL: " + operatorService.RepInfo.MyUrl + ", " + "<" + log + ">"); //Checks availability to process a new tuple while (operatorService.RepFreeze) { } if (operatorService.RepCrash) { Console.WriteLine("HELP ME I AM GOING TO CRASH!! NOOOOO!!"); return; } Thread.Sleep(operatorService.RepInterval); } } else { Console.WriteLine("Processed tuple " + t.toString() + " and rejected."); } } }