public static void exit() { bool b = Program.args.benchmark; //Program.args.benchmark = false;//do not trigger threadAbort messages unless they are unexpected aborts. try { SlaveReceiver.Stop(1); } catch (Exception) { } try { ReceiverTool.Stop(1); } catch (Exception) { } try { Master.MasterCrashChecker.Abort(1); } catch (Exception) { } try { Master.publisher.Abort(1); } catch (Exception) { } try { SlaveMsgConsumer.Stop(); } catch (Exception) { } if (Program.args.benchmark = b) { showStat(); } Application.Exit(); return; }
/// <summary> /// This function allows to change parameters at run-time without ceasing to receive broadcasted message. /// To trigger this function, a broadcast message must be sent to the arguments.broadcastPort_Slaves port, /// containing serialized object instance of myMessage class with msg.key = MessageType.argumentChange and msg.data = Json-stringified-arguments. /// </summary> public static void HotRestart() { IPAddress tmp = IPAddress.Parse(Program.args.broadcastAddress); Slave.broadcastToSlaveEP = new IPEndPoint(tmp, Program.args.broadcastPort_Slaves); Master.canPublish = new Semaphore(0, int.MaxValue);//todo: check //myKafka.kafkatest(); //myKafka.send(new myMessage[]{new myMessage(MessageType.confirmMessageSuccess_Single, "ProducerA first test")}); //return; ReceiverTool.staticInit(); SlaveReceiver.staticInit(); Slave.staticInit(); myKafka.staticInit(); SlaveMsgConsumer.staticInit(); /*var Client = new UdpClient(); * var RequestData = Encoding.ASCII.GetBytes("SomeRequestData"); * var ServerEp = new IPEndPoint(IPAddress.Any, 0); * * Client.EnableBroadcast = true; * Client.Send(RequestData, RequestData.Length, new IPEndPoint(IPAddress.Broadcast, 8888)); */ //Socket sock = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp); //sock.Poll(1,SelectMode.SelectWrite); //tmp = IPAddress.Broadcast; //Slave.senderToSlave.Client.Bind(Program.broadcastEP); foreach (Slave a in args.replicatorsList) { a.coInitializer(); } if (Slave.self == null) { pex("Argument error: Exactly one slave must have \"isSelf = true\". It is needed to know what slave id this instance has."); } new Master(); while (ReceiverTool.all.Count < args.toolReceiverThreads) { new ReceiverTool(); } while (SlaveReceiver.all.Count < args.slaveReceiverThreads) { new SlaveReceiver(); } //only happening in case of hot restart for argument change: the receiver threads will never stop collecting. //NB: in caso di riduzione dei thread potrebbe verificarsi la perdita di un messaggio se il thread viene interrotto tra la ricezione e l'accodamento. fare un fermo sincronizzato però implicherebbe delle operazioni durante la normale esecuzione che rallenterebbero il throughput. while (ReceiverTool.all.Count > args.toolReceiverThreads) { ReceiverTool.RemoveOne(); } while (SlaveReceiver.all.Count > args.slaveReceiverThreads) { SlaveReceiver.RemoveOne(); } for (int i = 0; i < ReceiverTool.all.Count; i++) { ReceiverTool.all[i].myThread.Name = "Tool Broadcast Broadcast Receiver " + (i + 1) + "/" + ReceiverTool.all.Count; } for (int i = 0; i < SlaveReceiver.all.Count; i++) { SlaveReceiver.all[i].myThread.Name = "IntraCommunication Receiver " + (i + 1) + "/" + SlaveReceiver.all.Count; } new SlaveMsgConsumer().start(); SlaveReceiver.Start(); ReceiverTool.Start(); //MessageBox.Show("Done"); if (args.enableGUI && GUI.thiss == null) { //args.enableGUI = false;//debug only Thread.CurrentThread.Name = "MainGuiThread"; Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); Application.Run(new GUI()); } }