コード例 #1
0
 private void RunCloudMake(Vsync.Group vsyncGroup)
 {
     _dependencyStructure.Run();
     if (_rank == 0)
     {
         Dist(vsyncGroup, _dependencyStructure.GetModifiedConfigFiles(),
              _dependencyStructure.GetModifiedCloudMakeConfigFiles());
     }
     else
     {
         vsyncGroup.P2PSend(new Address(_leaders [_partition] [_rank - 1]), CloudManager.RUN_CLOUD_MAKE);
     }
     _dependencyStructure.Reset();
 }
コード例 #2
0
        private void ModifiedState(Vsync.Group vsyncGroup, string path, string name)
        {
            XmlDocument xmlDoc   = new XmlDocument();
            string      filename = _name + "/" + name;
            string      content;

            xmlDoc.Load(path);
            content = xmlDoc.OuterXml;
            if (_localCloudMakefile.Compatible(filename).Count > 0)
            {
                UpdateState(vsyncGroup, filename, content);
            }
            for (int i = 0; i < _leaderCloudMakefiles.Count; i++)
            {
                if (_leaderCloudMakefiles [i].Compatible(filename).Count > 0)
                {
                    vsyncGroup.P2PSend(new Address(_leaders [i] [0]), CloudManager.UPDATE_STATE, filename, content);
                }
            }
        }
コード例 #3
0
        private void  ProcessMessages(Vsync.Group vsyncGroup, List <Tuple <MessageType, List <string> > > msgs)
        {
            foreach (Tuple <MessageType, List <string> > msg  in msgs)
            {
                MessageType   type = msg.Item1;
                MessageType   tempType;
                List <string> parameters = msg.Item2;
                List <string> tempParameters = null;
                string        vsyncAddress, memberName, filename, xmlString, procName, configFilename;
                int           minPartition, partition, last;

                WriteMessage(type, parameters);
                switch (type)
                {
                case MessageType.NEW_NODE:
                    vsyncAddress = parameters [0];
                    CloudManager.WriteLine(_debugFilename, vsyncAddress.ToString());
                    vsyncGroup.P2PSend(new Address(vsyncAddress), CloudManager.LEADER_INFO, _vsyncAddress,
                                       _partition, _rank);
                    break;

                case MessageType.FAIL_NODE:
                    vsyncAddress = parameters [0];
                    partition    = CloudManager.FindPartition(_leaders, _reserveLeaders, vsyncAddress);
                    if (partition >= 0)
                    {
                        throw new NotImplementedException();
                    }
                    else if (partition == -1)
                    {
                        _reserveLeaders.Remove(vsyncAddress);
                    }
                    else if (_addressToName.ContainsKey(vsyncAddress))
                    {
                        memberName = _addressToName [vsyncAddress];
                        _addressToName.Remove(vsyncAddress);
                        _nameToAddress.Remove(memberName);
                        if ((_state == State.ACTIVE) && IsEventInPartition(memberName + "/fail_node"))
                        {
                            if (_rank == 0)
                            {
                                if (_leaders [_partition].Count == 1)
                                {
                                    MemberLeave(memberName);
                                    _updatesDelivered += 1;
                                }
                                else
                                {
                                    _pending.Add(msg);
                                    vsyncGroup.P2PSend(new Address(_leaders [_partition] [_rank + 1]),
                                                       CloudManager.MEMBER_LEAVE, memberName);
                                }
                            }
                        }
                    }
                    break;

                case MessageType.MEMBER_JOIN:
                    vsyncAddress = parameters [0];
                    memberName   = parameters [1];
                    _addressToName.Add(vsyncAddress, memberName);
                    _nameToAddress.Add(memberName, vsyncAddress);
                    if ((_partition >= 0) && (_rank == 0) && (_rank == _leaders [_partition].Count - 1))
                    {
                        NewMember(memberName);
                        _updatesDelivered += 1;
                    }
                    else if ((_partition >= 0) && (_rank == 0))
                    {
                        tempType       = MessageType.NEW_MEMBER;
                        tempParameters = new List <string> ();
                        tempParameters.Add(memberName);
                        _pending.Add(new Tuple <MessageType, List <string> > (tempType, tempParameters));
                        vsyncGroup.P2PSend(new Address(_leaders [_partition] [_rank + 1]), CloudManager.NEW_MEMBER,
                                           memberName);
                    }
                    break;

                case MessageType.MEMBER_LEAVE:
                    if (!(_state == State.ACTIVE))
                    {
                        throw new Exception("CloudMakeLeader: Received MEMBER_LEAVE without being active.");
                    }
                    memberName = parameters [0];
                    if (_rank == _leaders [_partition].Count - 1)
                    {
                        MemberLeave(memberName);
                        _updatesDelivered += 1;
                        if (_rank > 0)
                        {
                            vsyncGroup.P2PSend(new Address(_leaders [_partition] [_rank - 1]), CloudManager.ACK);
                        }
                    }
                    else
                    {
                        _pending.Add(msg);
                        vsyncGroup.P2PSend(new Address(_leaders [_partition] [_rank + 1]), CloudManager.MEMBER_LEAVE,
                                           memberName);
                    }
                    break;

                case MessageType.LEADER_JOIN:
                    vsyncAddress = parameters [0];
                    minPartition = CloudManager.FindMinPartition(_leaders);
                    if ((minPartition >= 0) && (_leaders [minPartition].Count < _nreplicas))
                    {
                        last = _leaders [minPartition].Count - 1;
                        _leaders [minPartition].Add(vsyncAddress);
                        CloudManager.WriteLine(_debugFilename, "Previous Leader: " + _leaders [minPartition] [last]);
                        CloudManager.WriteLine(_debugFilename, "Me: " + _vsyncAddress);
                        if ((_state == State.ACTIVE) && (_leaders [minPartition] [last] == _vsyncAddress))
                        {
                            Tuple <List <string>, List <string>, List <string> > triple = GetState();

                            vsyncGroup.P2PSend(new Address(_leaders [minPartition] [last + 1]),
                                               CloudManager.STATE_TRANSFER, triple.Item1, triple.Item2, triple.Item3);
                        }
                    }
                    else
                    {
                        _reserveLeaders.Add(vsyncAddress);
                    }
                    break;

                case MessageType.NEW_MEMBER:
                    memberName = parameters [0];
                    CloudManager.WriteLine(_debugFilename, "Partition: " + _partition.ToString());
                    if (_rank == _leaders [_partition].Count - 1)
                    {
                        CloudManager.WriteLine(_debugFilename, "Call NewMember.");
                        NewMember(memberName);
                        _updatesDelivered += 1;
                        if (_rank > 0)
                        {
                            vsyncGroup.P2PSend(new Address(_leaders [_partition] [_rank - 1]), CloudManager.ACK);
                        }
                    }
                    else
                    {
                        _pending.Add(msg);
                        vsyncGroup.P2PSend(new Address(_leaders [_partition] [_rank + 1]), CloudManager.NEW_MEMBER,
                                           memberName);
                    }
                    break;

                case MessageType.NEW_CONFIG:
                    configFilename = parameters [0];
                    CloudManager.WriteLine(_debugFilename, "Partition: " + _partition.ToString());
                    if (_rank == _leaders [_partition].Count - 1)
                    {
                        CloudManager.WriteLine(_debugFilename, "Call NewConfig.");
                        NewConfig(configFilename);
                        CloudManager.WriteLine(_debugFilename, "Finished NewConfig.");
                        _updatesDelivered += 1;
                        if (_rank > 0)
                        {
                            vsyncGroup.P2PSend(new Address(_leaders [_partition] [_rank - 1]), CloudManager.ACK);
                        }
                    }
                    else
                    {
                        _pending.Add(msg);
                        vsyncGroup.P2PSend(new Address(_leaders [_partition] [_rank + 1]), CloudManager.NEW_CONFIGS,
                                           parameters);
                    }
                    break;

                case MessageType.STOPPED_PROC:
                    if (_state != State.ACTIVE)
                    {
                        throw new Exception("CloudMakeLeader: Received STOPPED_PROC without being active.");
                    }
                    memberName = parameters [0];
                    procName   = parameters [1];
                    if (_rank == _leaders [_partition].Count - 1)
                    {
                        StoppedProc(memberName, procName);
                        _updatesDelivered += 1;
                        if (_rank > 0)
                        {
                            vsyncGroup.P2PSend(new Address(_leaders [_partition] [_rank - 1]), CloudManager.ACK);
                        }
                    }
                    else
                    {
                        _pending.Add(msg);
                        vsyncGroup.P2PSend(new Address(_leaders [_partition] [_rank + 1]), CloudManager.STOPPED_PROC,
                                           memberName, procName);
                    }
                    break;

                case MessageType.UPDATE_STATE:
                    if (_state != State.ACTIVE)
                    {
                        throw new Exception("CloudMakeLeader: Received UPDATE_STATE without being active");
                    }
                    filename  = parameters [0];
                    xmlString = parameters [1];
                    if (_rank == _leaders [_partition].Count - 1)
                    {
                        UpdateState(filename, xmlString);
                        _updatesDelivered += 1;
                        if (_rank > 0)
                        {
                            vsyncGroup.P2PSend(new Address(_leaders [_partition] [_rank - 1]), CloudManager.ACK);
                        }
                    }
                    else
                    {
                        _pending.Add(msg);
                        vsyncGroup.P2PSend(new Address(_leaders [_partition] [_rank + 1]), CloudManager.UPDATE_STATE,
                                           filename, xmlString);
                    }
                    break;

                case MessageType.ACK:
                    tempType       = _pending [0].Item1;
                    tempParameters = _pending [0].Item2;
                    switch (tempType)
                    {
                    case MessageType.NEW_MEMBER:
                        CloudManager.WriteLine(_debugFilename, "Call NewMember.");
                        memberName = tempParameters [0];
                        NewMember(memberName);
                        break;

                    case MessageType.NEW_CONFIG:
                        configFilename = tempParameters [0];
                        CloudManager.WriteLine(_debugFilename, "Call NewConfig.");
                        NewConfig(configFilename);
                        CloudManager.WriteLine(_debugFilename, "Finished NewConfig.");
                        break;

                    case MessageType.MEMBER_LEAVE:
                        memberName = tempParameters [0];
                        MemberLeave(memberName);
                        break;

                    case MessageType.STOPPED_PROC:
                        memberName = tempParameters [0];
                        procName   = tempParameters [1];
                        StoppedProc(memberName, procName);
                        break;

                    case MessageType.UPDATE_STATE:
                        filename  = tempParameters [0];
                        xmlString = tempParameters [1];
                        UpdateState(filename, xmlString);
                        break;

                    default:
                        throw new Exception("CloudMakeLeader: Unknown Message Type " + _pending [0].Item1.ToString() +
                                            " in pending queue.");
                    }
                    _updatesDelivered += 1;
                    _pending.RemoveAt(0);
                    if (_rank > 0)
                    {
                        vsyncGroup.P2PSend(new Address(_leaders [_partition] [_rank - 1]), CloudManager.ACK);
                    }
                    break;

                case MessageType.RUN_CLOUD_MAKE:
                    RunCloudMake(vsyncGroup);
                    break;

                case MessageType.STATE_TRANSFER:
                    if (_state != State.WAITFORSTATE)
                    {
                        throw new Exception("CloudMakeLeader: Received STATE_TRANSFER without being at WAITFORSTATE " +
                                            "state");
                    }

                    List <string> directories  = new List <string> ();
                    List <string> xmlFilenames = new List <string> ();
                    List <string> xmlContents  = new List <string> ();

                    int i = 0;
                    while ((parameters.Count > 2 * i + 1) && (parameters [2 * i + 1] == ""))
                    {
                        string dir = parameters [2 * i];

                        Directory.CreateDirectory(dir);
                        directories.Add(dir);
#if DEBUG
                        CloudManager.WriteLine(_debugFilename, "State Transfer Directory: " + dir);
#endif
                        i++;
                    }
                    while (parameters.Count > 2 * i + 1)
                    {
                        string      xmlFilename = parameters [2 * i];
                        string      xmlContent  = parameters [2 * i + 1];
                        XmlDocument xmlDoc      = new XmlDocument();

                        xmlFilenames.Add(xmlFilename);
                        xmlContents.Add(xmlContent);
#if DEBUG
                        CloudManager.WriteLine(_debugFilename, "State Transfer Filename: " + xmlFilename);
#endif
                        xmlDoc.LoadXml(xmlContent);
                        xmlDoc.Save(xmlFilename);
                        i++;
                    }
                    _state = State.ACTIVE;
                    if (_rank != _leaders [_partition].Count - 1)
                    {
                        vsyncGroup.P2PSend(new Address(_leaders [_partition] [_rank + 1]),
                                           CloudManager.STATE_TRANSFER, directories, xmlFilenames, xmlContents);
                    }
                    break;

                case MessageType.SEND_PENDING:
                    throw new NotImplementedException();

                default:
                    throw new Exception("CloudMakeLeader: I should not have received " + msg.ToString() +
                                        " message.");
                }
                CloudManager.WriteLine(_debugFilename, "Pending:");
                foreach (Tuple <MessageType, List <string> > tempMsg in _pending)
                {
                    WriteMessage(tempMsg.Item1, tempMsg.Item2);
                }
            }
        }
コード例 #4
0
        private void Dist(Vsync.Group vsyncGroup, HashSet <string> activeConfigFiles,
                          HashSet <string> activeCloudMakeConfigFiles)
        {
            Tuple <HashSet <string>, List <RemoteProcessInfo> > processedInfo =
                ProcessCloudMakeConfigFiles(vsyncGroup, activeCloudMakeConfigFiles);
            HashSet <string>         additionalActiveConfigFiles = new HashSet <string> ();
            List <RemoteProcessInfo> remoteProcesses             = processedInfo.Item2;

            foreach (string activeConfigFile in processedInfo.Item1)
            {
                if (File.Exists(activeConfigFile))
                {
                    additionalActiveConfigFiles.Add(activeConfigFile);
                }
            }
#if DEBUG
            CloudManager.WriteLine(_debugFilename, "Active config files:");
            foreach (string filename in activeConfigFiles)
            {
                CloudManager.WriteLine(_debugFilename, filename);
            }
            CloudManager.WriteLine(_debugFilename, "");

            CloudManager.WriteLine(_debugFilename, "Active CloudMake config files:");
            foreach (string filename in activeCloudMakeConfigFiles)
            {
                CloudManager.WriteLine(_debugFilename, filename);
            }
            CloudManager.WriteLine(_debugFilename, "");
#endif
            activeConfigFiles.UnionWith(additionalActiveConfigFiles);
#if DEBUG
            CloudManager.WriteLine(_debugFilename, "Files to Distribute:");
            foreach (string filename in activeConfigFiles)
            {
                CloudManager.WriteLine(_debugFilename, filename);
            }
            CloudManager.WriteLine(_debugFilename, "");
#endif
            foreach (string activeConfigFile in activeConfigFiles)
            {
                List <string> fields     = new List <string> (activeConfigFile.Split('/'));
                string        nodename   = fields [0];
                List <string> fieldsList = fields.GetRange(1, fields.Count - 1);
                string        path       = String.Join("/", fieldsList);
                XmlDocument   xmlDoc     = new XmlDocument();
                string        filename   = String.Join(Path.DirectorySeparatorChar.ToString(), fields);
                string        content;
                List <string> pathList    = new List <string> ();
                List <string> contentList = new List <string> ();

                xmlDoc.Load(filename);
                content = xmlDoc.OuterXml;
#if DEBUG
                CloudManager.WriteLine(_debugFilename, "Distribute the content of " + filename + " to " + nodename);
#endif
                pathList.Add(path);
                contentList.Add(content);
                if (_nameToAddress.ContainsKey(nodename))
                {
                    vsyncGroup.P2PSend(new Address(_nameToAddress [nodename]), CloudManager.UPDATE_CONFIGS, pathList,
                                       contentList);
                }
            }

            foreach (RemoteProcessInfo proc in remoteProcesses)
            {
                List <string> nameList = new List <string> ();
                List <string> pathList = new List <string> ();
                List <string> execList = new List <string> ();
                List <string> argsList = new List <string> ();
                string        nodename;

                if (proc.GetAction() == Action.RUN)
                {
                    nameList.Add(proc.GetName());
                    pathList.Add(proc.GetPath());
                    execList.Add(proc.GetExec());
                    argsList.Add(proc.GetArgs());
                    nodename = proc.GetNodename();
                    if (_nameToAddress.ContainsKey(nodename))
                    {
                        vsyncGroup.P2PSend(new Address(_nameToAddress [nodename]), CloudManager.RUN_PROCESSES,
                                           nameList, pathList, execList, argsList);
                    }
                }
                else
                {
                    nameList.Add(proc.GetName());
                    nodename = proc.GetNodename();
                    if (_nameToAddress.ContainsKey(nodename))
                    {
                        vsyncGroup.P2PSend(new Address(_nameToAddress [nodename]), CloudManager.KILL_PROCESSES,
                                           nameList);
                    }
                }
            }
        }
コード例 #5
0
        ProcessCloudMakeConfigFiles(Vsync.Group vsyncGroup, HashSet <string> cloudMakeConfigFiles)
        {
            List <RemoteProcessInfo>            remoteProcesses = new List <RemoteProcessInfo> ();
            List <string>                       statePathList   = new List <string> ();
            List <string>                       stateNameList   = new List <string> ();
            Dictionary <int, HashSet <string> > configFiles     = new Dictionary <int, HashSet <string> > ();

            foreach (string cloudMakeConfigFile in cloudMakeConfigFiles)
            {
                XmlDocument xmlDoc = new XmlDocument();
                XmlNode     xmlNode;
                string      nodename = cloudMakeConfigFile.Substring(0, cloudMakeConfigFile.IndexOf('/'));

                xmlDoc.Load(cloudMakeConfigFile);
                xmlNode = xmlDoc.DocumentElement;
                foreach (XmlNode childNode in xmlNode.ChildNodes)
                {
                    switch (childNode.Name)
                    {
                    case ("process"):
                        if (childNode.Attributes ["action"].Value == "Run")
                        {
                            string name = childNode ["name"].InnerText;
                            string path = childNode ["path"].InnerText;
                            string exec = childNode ["exec"].InnerText;
                            string args = childNode ["args"].InnerText;
#if DEBUG
                            CloudManager.WriteLine(_debugFilename, "Run process " + name + ".");
#endif
                            remoteProcesses.Add(new RemoteProcessInfo(Action.RUN, nodename, name, path, exec, args));
                        }
                        else if (childNode.Attributes ["action"].Value == "Kill")
                        {
                            string name = childNode ["name"].InnerText;
#if DEBUG
                            CloudManager.WriteLine(_debugFilename, "Kill process " + name + ".");
#endif
                            remoteProcesses.Add(new RemoteProcessInfo(Action.KILL, nodename, name));
                        }
                        break;

                    case ("stateFile"):
                        string statePath = childNode ["path"].InnerText;
                        string stateName = childNode ["name"].InnerText;

                        statePathList.Add(statePath);
                        stateNameList.Add(stateName);
                        break;

                    case ("configFile"):
                        string configPath     = childNode ["path"].InnerText;
                        string configName     = childNode ["name"].InnerText;
                        string configFilename = (configPath == "") ? nodename + "/" + configName : nodename + "/" +
                                                configPath + "/" + configName;

                        for (int i = 0; i < _leaderCloudMakefiles.Count; i++)
                        {
                            if (_leaderCloudMakefiles [i].Compatible(configFilename).Count > 0)
                            {
                                if (!configFiles.ContainsKey(i))
                                {
                                    configFiles [i] = new HashSet <string> ();
                                }
                                configFiles [i].Add(configFilename);
                            }
                        }

                        if ((_localCloudMakefiles.ContainsKey(nodename)) &&
                            (_localCloudMakefiles [nodename].Compatible(configFilename).Count > 0))
                        {
                            List <string> parameters = new List <string> ();

                            parameters.Add(configFilename);
                            vsyncGroup.P2PSend(new Address(_nameToAddress [nodename]), CloudManager.NEW_CONFIGS,
                                               parameters);
                        }
                        break;

                    default:
#if DEBUG
                        CloudManager.WriteLine(_debugFilename,
                                               "CloudMakeLeader: Operation " + childNode.Name + " is not supported from CloudMakefile.");
#endif
                        break;
                    }
                }

                foreach (int i in configFiles.Keys)
                {
                    if (i == _partition)
                    {
                        foreach (string configFilename in configFiles[i])
                        {
                            NewConfig(configFilename);
                        }
                    }
                    else
                    {
                        vsyncGroup.P2PSend(new Address(_leaders [i] [0]), CloudManager.NEW_CONFIGS,
                                           new List <string> (configFiles [i]));
                    }
                }

                if (statePathList.Count > 0)
                {
                    vsyncGroup.P2PSend(new Address(_nameToAddress [nodename]), CloudManager.ASK_STATES, statePathList,
                                       stateNameList);
                }
            }

            if (configFiles.ContainsKey(_partition))
            {
                return(new Tuple <HashSet <string>, List <RemoteProcessInfo> > (configFiles [_partition], remoteProcesses));
            }
            return(new Tuple <HashSet <string>, List <RemoteProcessInfo> > (new HashSet <string> (), remoteProcesses));
        }
コード例 #6
0
        private void ProcessMessages(Vsync.Group vsyncGroup, List <Tuple <MessageType, List <string> > > msgs)
        {
            foreach (Tuple <MessageType, List <string> > msg in msgs)
            {
                MessageType   type = msg.Item1;
                List <string> parameters = msg.Item2;
                string        vsyncAddress, procName, path, exec, args, filename, content, configFilename;
#if DEBUG
                WriteMessage(type, parameters);
#endif
                switch (type)
                {
                case MessageType.NEW_NODE:
                    if (parameters.Count != 1)
                    {
                        throw new Exception("CloudMakeLocal: NEW_NODE: Does not accept " +
                                            parameters.Count.ToString() + " parameters.");
                    }
                    vsyncAddress = parameters [0];
                    vsyncGroup.P2PSend(new Address(vsyncAddress), CloudManager.MEMBER_INFO, _vsyncAddress, _name);
                    break;

                case MessageType.FAIL_NODE:
                    break;

                case MessageType.MEMBER_JOIN:
                    MemberJoin(vsyncGroup);
                    break;

                case MessageType.LEADER_JOIN:
                    if (parameters.Count != 1)
                    {
                        throw new Exception("CloudMakeLocal: LEADER_JOIN: Does not accept " +
                                            parameters.Count.ToString() + " parameters.");
                    }
                    vsyncAddress = parameters [0];
                    CloudManager.AddLeader(_leaders, _reserveLeaders, _nreplicas, vsyncAddress);
                    break;

                case MessageType.NEW_CONFIG:
                    if (parameters.Count != 1)
                    {
                        throw new Exception("CloudMakeLocal: NEW CONFIG: Should only have one configFilename.");
                    }
                    configFilename = parameters [0];
                    NewConfig(configFilename);
                    break;

                case MessageType.RUN_PROCESS:
                    procName = parameters [0];
                    path     = parameters [1];
                    exec     = parameters [2];
                    args     = parameters [3];
                    RunProcess(procName, path, exec, args);
                    break;

                case MessageType.KILL_PROCESS:
                    procName = parameters [0];
                    KillProcess(procName);
                    break;

                case MessageType.UPDATE_CONFIG:
                    filename = parameters [0];
                    content  = parameters [1];
                    UpdateConfig(filename, content);
                    break;

                case MessageType.ASK_STATE:
                    path     = parameters [0];
                    filename = parameters [1];
                    AskState(vsyncGroup, path, filename);
                    break;

                default:
                    throw new Exception("CloudMakeLocal: I should not have received " + msg.ToString() +
                                        " message.");
                }
            }
        }
コード例 #7
0
        private Tuple <HashSet <string>, List <RemoteProcessInfo> > ProcessCloudMakeConfigFile(Vsync.Group vsyncGroup)
        {
            string      cloudMakeConfigFilename = _name + "/CloudMake/config.xml";
            XmlDocument xmlDoc = new XmlDocument();
            XmlNode     xmlNode;
            List <RemoteProcessInfo>            processes         = new List <RemoteProcessInfo> ();
            List <string>                       statePathList     = new List <string> ();
            List <string>                       stateFilenameList = new List <string> ();
            Dictionary <int, HashSet <string> > configFiles       = new Dictionary <int, HashSet <string> > ();
            HashSet <string>                    localConfigFiles  = new HashSet <string> ();

            xmlDoc.Load(cloudMakeConfigFilename);
            xmlNode = xmlDoc.DocumentElement;
            foreach (XmlNode childNode in xmlNode.ChildNodes)
            {
                switch (childNode.Name)
                {
                case ("process"):
                    if (childNode.Attributes ["action"].Value == "Run")
                    {
                        string name = childNode ["name"].InnerText;
                        string path = childNode ["path"].InnerText;
                        string exec = childNode ["exec"].InnerText;
                        string args = childNode ["args"].InnerText;
#if DEBUG
                        CloudManager.WriteLine(_debugFilename, "Run process " + name + ".");
#endif
                        processes.Add(new RemoteProcessInfo(Action.RUN, _name, name, path, exec, args));
                    }
                    else if (childNode.Attributes ["action"].Value == "Kill")
                    {
                        string name = childNode ["name"].InnerText;
#if DEBUG
                        CloudManager.WriteLine(_debugFilename, "Kill process " + name + ".");
#endif
                        processes.Add(new RemoteProcessInfo(Action.KILL, _name, name));
                    }
                    break;

                case ("stateFile"):
                    string statePath = childNode ["path"].InnerText;
                    string stateName = childNode ["name"].InnerText;

                    if (statePath == "")
                    {
                        statePath = _curDirectory;
                    }
                    else
                    {
                        statePath = _curDirectory + Path.DirectorySeparatorChar.ToString() + statePath;
                    }
                    statePathList.Add(statePath);
                    stateFilenameList.Add(stateName);
                    break;

                case ("configFile"):
                    string configPath     = childNode ["path"].InnerText;
                    string configName     = childNode ["name"].InnerText;
                    string configFilename = (configPath == "") ? _name + "/" + configName : _name + "/" +
                                            configPath + "/" + configName;

                    for (int i = 0; i < _leaderCloudMakefiles.Count; i++)
                    {
                        if (_leaderCloudMakefiles [i].Compatible(configFilename).Count > 0)
                        {
                            if (!configFiles.ContainsKey(i))
                            {
                                configFiles [i] = new HashSet <string> ();
                            }
                            configFiles [i].Add(configFilename);
                        }
                    }

                    if (_localCloudMakefile.Compatible(configFilename).Count > 0)
                    {
                        NewConfig(configFilename);
                        localConfigFiles.Add(configFilename);
                    }
                    break;

                default:
                    throw new Exception("CloudMakeLocal Config: Operation " + childNode.Name + " is not supported " +
                                        "from CloudMake.");
                }
            }

            foreach (int i in configFiles.Keys)
            {
                vsyncGroup.P2PSend(new Address(_leaders [i] [0]), CloudManager.NEW_CONFIGS,
                                   new List <string> (configFiles [i]));
            }

            for (int i = 0; i < statePathList.Count; i++)
            {
                AskState(vsyncGroup, statePathList [i], stateFilenameList [i]);
            }

            return(new Tuple <HashSet <string>, List <RemoteProcessInfo> > (localConfigFiles, processes));
        }