//public int receivePort, sendPort; /* * public Slave(SlaveArgJson arg){ * this.id = arg.id; * this.ip = Program.stringToIP(this.ip_string = arg.adress); * this.coInitializer(); * }*/ public static List <Slave> staticInit() { //todo: in hotRestart chiama esplicitamente tutti gli staticInit e aggiungi clausole per chiudere i client già aperti sovrascrivendoli. //cleanup for HotRestart if (Slave.senderToSlave != null) { senderToSlave.Close(); } if (Slave.ensureUniqueID != null) { ensureUniqueID.Clear(); lock (Slave.all) foreach (Slave s in Slave.all) { Slave.Remove(s); } } //real initialization Slave.senderToSlave = new UdpClient() { EnableBroadcast = true }; Slave.senderToSlave.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.NoDelay, true);//nagle's algorithm should work only in tpc, but i want to be sure that it will not execute, that would be a problem. Slave.senderToSlave.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.NoChecksum, false); Slave.senderToSlave.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true); Slave.senderToSlave.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ExclusiveAddressUse, false); Slave.senderToSlave.ExclusiveAddressUse = false; Slave.senderToSlave.EnableBroadcast = true; Slave.all = new List <Slave>(); Slave.ensureUniqueID = new Dictionary <ulong, Slave>(); return(Slave.all); }
/// <summary> /// processing executed after message got dequeued. /// </summary> public void consume() { Program.logSlave("consuming :" + this.ToPrintString()); Slave s; ulong id; int removedCount; switch (type) { case MessageType.argumentChange: StartupArgJson args; try { args = StartupArgJson.deserialize(this.data); } catch (Exception e) { Program.pe(this.type + " body is not deserializable: " + this.data, e); break; } if (args == null || !args.Validate()) { Program.pe(this.type + " body is deserializable but with invalid content: " + this.data); break; } Program.args = args; Master.MasterCrashChecker.Abort(); Master.MasterCrashChecker = null; new Thread(Program.HotRestart).Start(); /* * string[] arr = this.data.Split(myMessage.separator); * foreach (string str in arr) { * string[] kv = str.Split(myMessage.secondSeparator); * ulong slaveID; * if (!ulong.TryParse(kv[0], out slaveID)) { Program.pe("Unexpected slaveID key ("+kv[0]+") found in the body of messagetype."+this.type); continue; } * * }*/ //todo: crea anche un software che generi messaggi di ripartizionamento per gestire dinamicamente tutte le partizioni, un supermaster break; case MessageType.masterChange: //if required in future trigger messageType.dinamicallyAddSlave, per ora va tutto bene anche se il nuovo master non era nella lista slaves. string[] split = this.data.Split(myMessage.separator); if (!ulong.TryParse(split[0], out id)) { Program.pe(this.type + " have non-numerical body; expected two numeric id separated by a '" + myMessage.separator + "', found instead: " + this.data); break; } Slave oldMaster = Slave.getFromID(id); if (oldMaster == null) { break; } if (!ulong.TryParse(split[0], out id)) { Program.pe(this.type + " have non-numerical body; expected two numeric id separated by a '" + myMessage.separator + "', found instead: " + this.data); break; } Slave newMaster = Slave.getFromID(id); if (newMaster == null) { break; } if (Master.currentMaster == oldMaster) { Master.changeMaster(newMaster); //master checker msg received } Slave.Remove(oldMaster); break; case MessageType.dinamicallyRemoveSlave: if (!ulong.TryParse(this.data, out id)) { Program.pe(this.type + " have non-numerical body; expected numeric id, found: " + this.data); break; } s = Slave.getFromID(id); if (s == null) { break; } Slave.Remove(s); break; case MessageType.dinamicallyAddSlave: Slave.deserializeOrGet(this.data); if (Master.iAmTheMaster) { myMessage m = new myMessage(MessageType.provideSlaveList, ""); foreach (Slave s2 in Slave.all) { m.data += ";" + s2.serialize(); } m.data = m.data.Substring(1); m.launchToOutput(); } break; case MessageType.provideSlaveList: Volatile.Write(ref Master.lastMasterUpdate, DateTime.Now.Ticks); string[] jsons = this.data.Split(myMessage.separator); lock (Slave.all) foreach (string str in jsons) { Slave.deserializeOrGet(str); } break; case MessageType.confirmMessageSuccess_Single: Volatile.Write(ref Master.lastMasterUpdate, DateTime.Now.Ticks); removedCount = ReceiverTool.messageQueue.get(this.data, true) == null ? 0 : 1; Program.logSlave(removedCount + " removed from queue."); break; case MessageType.confirmMessageSuccess_Batch: Volatile.Write(ref Master.lastMasterUpdate, DateTime.Now.Ticks); removedCount = ReceiverTool.messageQueue.getOlderThan(this.data, true).Count; Program.logSlave(removedCount + " removed from queue."); break; case MessageType.xml: Program.pe("xml messages should be handled in Master thread without consuming."); return; default: case MessageType.uninitialized: Program.pe("uninitialized message consumed"); return; } }