void DetermineNextBuildMachine() { lock (_Lock) { if (_NextMachine != null) { // Current machine is still active so we just wait. return; } if (_bIsPaused) { // Machine is paused. Don't start any builds. return; } // Need to find a new chosen one among our build machines. As they are // currently all on one physical machine we don't want them to build in parallel. foreach (KeyValuePair <string, BuildMachine> entry in _Machines) { BuildMachine machine = entry.Value; // The build machine that is the most far behind the HEAD will be build first, rest is currently random. // Also, we can't build beyond the current HEAD revision. if ((_NextMachine == null || machine.Settings.Revision < _NextMachine.Settings.Revision) && machine.Settings.Revision < _HeadRevision) { _NextMachine = machine; } } } }
void CheckBuildMachineAliveStatus() { lock (_Lock) { List <string> deadMachines = new List <string>(); foreach (KeyValuePair <string, BuildMachine> entry in _Machines) { BuildMachine machine = entry.Value; machine.CurrentTimeout += iTimerInterval; // Is the machine dead? if (machine.CurrentTimeout > iBuildMachineTimeout) { Console.WriteLine("DetermineNextBuildMachine: Machine '{0}' is dead.", entry.Key); deadMachines.Add(entry.Key); if (machine == _NextMachine) { _NextMachine.State = BuildMachine.BuildMachineState.FatalError; _NextMachine = null; } continue; } } // Remove dead machines foreach (string sKey in deadMachines) { _Machines.Remove(sKey); } } }
private string HandleGETWork(string sID) { lock (_Lock) { if (!_Machines.ContainsKey(sID)) { Console.WriteLine("HandleGETWork: Unknown machine '{0}' requested work!", sID); return(null); } // Update timestamp. _Machines[sID].CurrentTimeout = 0; DetermineNextBuildMachine(); ezGETWorkResponse response = new ezGETWorkResponse(); // If the currently querying build machine is the 'chosen one' we allow it to build the next revision. if (_Machines[sID] == _NextMachine && _NextMachine.State == BuildMachine.BuildMachineState.Idle) { BuildMachine machine = _Machines[sID]; machine.CurrentTimeout = 0; machine.State = machine.NeedClean ? BuildMachine.BuildMachineState.RunBuildAndClean : BuildMachine.BuildMachineState.RunBuild; response.Revision = machine.Settings.Revision + 1; // Build next revision in line. response.Response = machine.NeedClean ? ezGETWorkResponse.WorkResponse.RunBuildAndClean : ezGETWorkResponse.WorkResponse.RunBuild; Console.WriteLine("HandleGETWork: Machine '{0}' is now building!", sID); } return(Newtonsoft.Json.JsonConvert.SerializeObject(response)); } }
private bool IsHibernationPossible() { if (_bHibernateOnIdle && !_bIsPaused) { // If we have no working machine and no machine is not at head we hibernate the PC. if (_NextMachine != null) { return(false); } foreach (KeyValuePair <string, BuildMachine> entry in _Machines) { BuildMachine machine = entry.Value; if (machine.State != BuildMachine.BuildMachineState.Idle) { return(false); } if (machine.Settings.Revision != _HeadRevision) { return(false); } } return(true); } return(false); }
void DetermineCurrentRevisionOfBuildMachine(BuildMachine machine) { int iHighestRev = -1; string sSafeConfigurationName = machine.Settings.ConfigurationName.Replace("_", ""); string sSeachCritera = String.Format("{0}_*.*", sSafeConfigurationName); // Iterate through all exiting build results and search for the last build revision. // If non exists, we start to build at HEAD revision, otherwise we continue to build in order. foreach (string file in System.IO.Directory.EnumerateFiles(_Settings.AbsOutputFolder, sSeachCritera, SearchOption.AllDirectories)) { string sFile = Path.GetFileNameWithoutExtension(file); string[] parts = sFile.Split('_'); if (parts.Count() >= 2) { int iRev = -1; try { iRev = Convert.ToInt32(parts[1]); if (iRev > iHighestRev) { iHighestRev = iRev; } } catch (FormatException) { continue; } } } if (iHighestRev > 0) { machine.Settings.Revision = iHighestRev; } else { // New build machines start to build at HEAD so we just pretend as if we are at the revision before HEAD. machine.Settings.Revision = _HeadRevision - 1; } }
private string ShowHelpPage() { lock (_Lock) { // Returns a very simple web page that shows all non-buildMachine related commands to the CNC tool. string sHeader = "<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.01//EN\" \"http://www.w3.org/TR/html4/strict.dtd\">\n" + "<html>\n<head>\n" + "<meta content=\"text/html; charset=ISO-8859-1\"\n" + "http-equiv=\"content-type\">\n" + "<title></title>\n" + "</head>\n<body>\n"; string sFooter = "</body>\n</html>\n"; string sHelpPage = sHeader; sHelpPage += string.Format("<br>HEAD: {0}<br>", _HeadRevision); sHelpPage += string.Format("<a href=\"/?type={0}\">Check HEAD revision</a><br>", (int)ezBuildRequestMessageType.GETCheckHEADRevision); sHelpPage += string.Format("<a href=\"/?type={0}&TO={1}&StartRevision={2}\">Repost last 5 revisions</a><br>", (int)ezBuildRequestMessageType.GETPostToAddress, _Settings.WebsiteServer, (_HeadRevision - 5).ToString()); sHelpPage += string.Format("<a href=\"/?type={0}\">Machine Status</a><br><br>", (int)ezBuildRequestMessageType.GETStatus); sHelpPage += string.Format("<br>Paused: {0}<br>", _bIsPaused ? "yes" : "no"); sHelpPage += string.Format("<a href=\"/?type={0}\">Pause</a><br>", (int)ezBuildRequestMessageType.GETPause); sHelpPage += string.Format("<a href=\"/?type={0}\">Resume</a><br><br>", (int)ezBuildRequestMessageType.GETResume); sHelpPage += string.Format("<br>Hibernate on idle: {0}<br>", _bHibernateOnIdle ? "yes" : "no"); sHelpPage += string.Format("<a href=\"/?type={0}\">Enable Hibernate on Idle</a><br>", (int)ezBuildRequestMessageType.GETEnableHibernateOnIdle); sHelpPage += string.Format("<a href=\"/?type={0}\">Disable Hibernate on Idle</a><br><br><br>", (int)ezBuildRequestMessageType.GETDisableHibernateOnIdle); foreach (KeyValuePair <string, BuildMachine> entry in _Machines) { BuildMachine machine = entry.Value; sHelpPage += string.Format("<a href=\"/?type={0}&ID={1}\">Clean {1}</a><br>", (int)ezBuildRequestMessageType.GETCleanBuild, machine.Settings.ConfigurationName); } sHelpPage += sFooter; return(sHelpPage); } }
public void Build(BuildMachine machine) { machine.BuildPartA(); machine.BuildPartB(); machine.BuildPartC(); }