/// <summary> /// There is a delay between a serverManager.CommitChanges() and the actual /// materialization of the configuration. /// /// This methods waits for a specific site to be available. /// </summary> public static void WaitForSiteToBeAvailable(string siteName, ILoggerInterface logger) { UtilsSystem.RetryWhile( () => { using (ServerManager sm = new ServerManager()) { // Site is ready when state is available var state = UtilsSystem.QueryEnumerable( sm.Sites, (s) => s.Name == siteName, (s) => s, (s) => s.Name, logger).Single().State; } }, (e) => true, 3000, logger); }
/// <summary> /// Stop a site /// </summary> /// <param name="p"></param> /// <param name="maxWait"></param> /// <returns></returns> private bool StopSite(Site p, int maxWait = WaitMaxForProcessMs) { var state = p.State; if (state == ObjectState.Stopped) { return(true); } if (state != ObjectState.Started) { return(false); } UtilsSystem.RetryWhile(() => p.Stop(), (e) => true, 2000, this.Logger); Stopwatch sw = Stopwatch.StartNew(); sw.Start(); while (true) { if (sw.ElapsedMilliseconds > maxWait) { break; } if (p.State == ObjectState.Stopped) { return(true); } Thread.Sleep(WaitPauseMs); } return(false); }
/// <summary> /// Remove a host mapping /// </summary> /// <param name="hostname">Use null to remove all host mappings for this application Id</param> /// <param name="owner"></param> public void RemoveHostsMapping(string owner, string hostname = null) { UtilsSystem.RetryWhile(() => this.DoRemoveHostsMapping(owner, hostname), (e) => e is IOException, 2000, this.Logger); }
/// <summary> /// Añade un mapping al fichero hosts, o lo actualiza en función del hostname. /// Evita añadir duplicados o conflictivos. /// </summary> /// <param name="address"></param> /// <param name="hostname"></param> /// <param name="owner"></param> public void AddHostsMapping(string address, string hostname, string owner) { UtilsSystem.RetryWhile(() => this.DoAddHostsMapping(address, hostname, owner), (e) => e is IOException, 2000, this.Logger); }
/// <summary> /// Start a site /// </summary> /// <param name="p"></param> /// <returns></returns> private bool StartSite(Site p) { if (p.State == ObjectState.Started) { return(true); } if (p.State != ObjectState.Stopped) { return(false); } try { // Try a couple of times before actually handling an exception UtilsSystem.RetryWhile(() => p.Start(), (e) => true, 3000, this.Logger); } catch (Exception e) { // This usually happens when a port is in-use if (Convert.ToString(e.HResult) == "-2147024864") { List <string> ports = new List <string>(); foreach (var binding in p.Bindings) { if (ports.Contains(binding.EndPoint.Port.ToString())) { continue; } ports.Add(binding.EndPoint.Port.ToString()); } // Let's give a hint into what ports might be in use.... var bindings = (from binding in p.Bindings select binding.Host + "@" + Convert.ToString(binding.EndPoint)); // Try to figure out what process is using the port... string process = null; try { var processes = UtilsProcessPort.GetNetStatPorts(); process = string.Join( ", " + Environment.NewLine, processes.Where((i) => ports.Contains(i.port_number)) .Select((i) => $"{i.process_name}:{i.port_number}")); } catch { // ignored } throw new Exception( "Cannot start website, a port or binding might be already in use by another application or website: " + Environment.NewLine + string.Join(", " + Environment.NewLine, bindings) + Environment.NewLine + "The following port usages have been detected:" + Environment.NewLine + process, e); } else if (Convert.ToString(e.HResult) == "-2146233088") { this.Logger.LogInfo(false, "Cannot start website: " + Environment.NewLine + e.Message + Environment.NewLine + e.InnerException?.Message); return(true); } else { throw; } } Stopwatch sw = Stopwatch.StartNew(); sw.Start(); while (true) { if (sw.ElapsedMilliseconds > WaitMaxForProcessMs) { break; } if (p.State == ObjectState.Started) { return(true); } Thread.Sleep(WaitPauseMs); } return(false); }