mirror of
https://github.com/tgstation/tgstation-server.git
synced 2026-08-26 14:37:44 +01:00
Merge pull request #412 from tgstation/402-AutoRestart
Allows changing remote port without full restart
This commit is contained in:
@@ -388,7 +388,9 @@ namespace TGS.CommandLine
|
||||
OutputProc(res);
|
||||
return ExitCode.ServerError;
|
||||
}
|
||||
OutputProc("Change will be applied after service restart");
|
||||
|
||||
Interface.Dispose(); //close the channels to prevent holding the service open
|
||||
|
||||
return ExitCode.Normal;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -453,48 +453,12 @@ namespace TGS.Interface
|
||||
}
|
||||
}
|
||||
|
||||
#region IDisposable Support
|
||||
/// <summary>
|
||||
/// To detect redundant <see cref="Dispose(bool)"/> calls
|
||||
/// </summary>
|
||||
private bool disposedValue = false;
|
||||
|
||||
/// <summary>
|
||||
/// Implements the <see cref="IDisposable"/> pattern. Calls <see cref="CloseAllChannels"/>
|
||||
/// </summary>
|
||||
/// <param name="disposing"><see langword="true"/> if <see cref="Dispose()"/> was called manually, <see langword="false"/> if it was from the finalizer</param>
|
||||
void Dispose(bool disposing)
|
||||
{
|
||||
if (!disposedValue)
|
||||
{
|
||||
if (disposing)
|
||||
{
|
||||
CloseAllChannels(true);
|
||||
}
|
||||
|
||||
// TODO: free unmanaged resources (unmanaged objects) and override a finalizer below.
|
||||
// TODO: set large fields to null.
|
||||
|
||||
disposedValue = true;
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: override a finalizer only if Dispose(bool disposing) above has code to free unmanaged resources.
|
||||
// ~Interface() {
|
||||
// // Do not change this code. Put cleanup code in Dispose(bool disposing) above.
|
||||
// Dispose(false);
|
||||
// }
|
||||
|
||||
/// <summary>
|
||||
/// Implements the <see cref="IDisposable"/> pattern
|
||||
/// </summary>
|
||||
public void Dispose()
|
||||
{
|
||||
// Do not change this code. Put cleanup code in Dispose(bool disposing) above.
|
||||
Dispose(true);
|
||||
// TODO: uncomment the following line if the finalizer is overridden above.
|
||||
// GC.SuppressFinalize(this);
|
||||
CloseAllChannels(true);
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
||||
@@ -331,5 +331,16 @@ namespace TGS.Server
|
||||
/// Warning: When a testmerge commit failed to be published
|
||||
/// </summary>
|
||||
ReferencePush = 7700,
|
||||
/// <summary>
|
||||
/// Info: When the root ServiceHost has been restarted
|
||||
/// Error: When restarting the root ServiceHost and an unrecoverable error was encountered
|
||||
/// </summary>
|
||||
RootHostRestart = 7800,
|
||||
/// <summary>
|
||||
/// Info: When an operation to change the remote access port begins
|
||||
/// Warning: When a port change operation fails and a revert is attempted
|
||||
/// Error: When the config could not be saved when attempting to change the remote access port
|
||||
/// </summary>
|
||||
RemoteAccessPortChange = 7900,
|
||||
}
|
||||
}
|
||||
|
||||
+68
-6
@@ -1,11 +1,11 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Specialized;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
using System.Security.Principal;
|
||||
using System.ServiceModel;
|
||||
using System.Threading.Tasks;
|
||||
using TGS.Interface;
|
||||
using TGS.Interface.Components;
|
||||
|
||||
@@ -104,6 +104,40 @@ namespace TGS.Server
|
||||
OnlineAllHosts();
|
||||
}
|
||||
|
||||
void SafeCloseServiceHost(ServiceHost host)
|
||||
{
|
||||
try
|
||||
{
|
||||
host.Close();
|
||||
}
|
||||
catch
|
||||
{
|
||||
host.Abort();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Attempts to reload <see cref="serviceHost"/>
|
||||
/// </summary>
|
||||
/// <returns><see langword="true"/> on success, <see langword="false"/> otherwise</returns>
|
||||
bool RestartHost()
|
||||
{
|
||||
lock (this)
|
||||
try
|
||||
{
|
||||
SafeCloseServiceHost(serviceHost);
|
||||
SetupService();
|
||||
serviceHost.Open();
|
||||
Logger.WriteInfo("Root ServiceHost restarted", EventID.RootHostRestart, LoggingID);
|
||||
return true;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Logger.WriteError(String.Format("An unrecoverable error occurred while attempting to restart the root ServiceHost! Error: {0}", e.ToString()), EventID.RootHostRestart, LoggingID);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Enumerates configured <see cref="IInstanceConfig"/>s. Detaches those that fail to load
|
||||
/// </summary>
|
||||
@@ -349,7 +383,7 @@ namespace TGS.Server
|
||||
{
|
||||
var host = I.Value;
|
||||
var instance = (Instance)host.SingletonInstance;
|
||||
host.Close();
|
||||
SafeCloseServiceHost(host);
|
||||
instance.Dispose();
|
||||
UnlockLoggingID(instance.LoggingID);
|
||||
}
|
||||
@@ -358,9 +392,9 @@ namespace TGS.Server
|
||||
{
|
||||
Logger.WriteError(e.ToString(), EventID.ServiceShutdownFail, LoggingID);
|
||||
}
|
||||
serviceHost.Close();
|
||||
SafeCloseServiceHost(serviceHost);
|
||||
Config.Save(DefaultConfigDirectory);
|
||||
}
|
||||
Config.Save(DefaultConfigDirectory);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
@@ -384,7 +418,35 @@ namespace TGS.Server
|
||||
{
|
||||
if (port == 0)
|
||||
return "Cannot bind to port 0";
|
||||
Config.RemoteAccessPort = port;
|
||||
ushort orig_port;
|
||||
lock (this)
|
||||
{
|
||||
orig_port = Config.RemoteAccessPort;
|
||||
if (port == orig_port)
|
||||
return null;
|
||||
try
|
||||
{
|
||||
//save first just in case
|
||||
Config.Save(DefaultConfigDirectory);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Logger.WriteError(e.ToString(), EventID.RemoteAccessPortChange, LoggingID);
|
||||
return String.Format("An error occurred: {0}", e.ToString());
|
||||
}
|
||||
Logger.WriteInfo(String.Format("Changing remote access port from {0} to {1}", orig_port, port), EventID.RemoteAccessPortChange, LoggingID);
|
||||
Config.RemoteAccessPort = port;
|
||||
}
|
||||
Task.Factory.StartNew(() =>
|
||||
{
|
||||
lock (this)
|
||||
if (!RestartHost())
|
||||
{
|
||||
Logger.WriteWarning(String.Format("Port change to {0} failed, Reverting to port {1}!", port, orig_port), EventID.RemoteAccessPortChange, LoggingID);
|
||||
Config.RemoteAccessPort = orig_port;
|
||||
RestartHost();
|
||||
}
|
||||
});
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -563,7 +625,7 @@ namespace TGS.Server
|
||||
var host = hosts[Name];
|
||||
hosts.Remove(Name);
|
||||
var inst = (Instance)host.SingletonInstance;
|
||||
host.Close();
|
||||
SafeCloseServiceHost(host);
|
||||
path = inst.ServerDirectory();
|
||||
inst.Offline();
|
||||
inst.Dispose();
|
||||
|
||||
Reference in New Issue
Block a user