Example #1
0
        //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;
            }
        }