Merge pull request #1343 from tgstation/NiceExperiment

Low prio DM + DMAPI DD, Normal prio live DD
This commit is contained in:
Jordan Brown
2021-10-31 01:02:06 -04:00
committed by GitHub
14 changed files with 111 additions and 30 deletions
+5 -1
View File
@@ -62,7 +62,7 @@ docker run \
--restart=always \ # Recommended for maximum uptime
--network="host" \ # Not recommended, eases networking setup if your sql server is on the same machine
--name="tgs" \ # Name for the container
--cap-add=sys_nice \ # Recommended, allows tgs to schedule DreamDaemon as a higher priority process
--cap-add=sys_nice \ # Recommended, allows TGS to lower the niceness of child processes if it sees fit
--init \ #Highly recommended, reaps potential zombie processes
-p 5000:5000 \ # Port bridge for accessing TGS, you can change this if you need
-p 0.0.0.0:<public game port>:<public game port> \ # Port bridge for accessing DreamDaemon
@@ -119,6 +119,10 @@ Create an `appsettings.Production.yml` file next to `appsettings.yml`. This will
- `General:GitHubAccessToken`: Specify a GitHub personal access token with no scopes here to highly mitigate the possiblity of 429 response codes from GitHub requests
- `Session:HighPriorityLiveDreamDaemon`: Boolean controlling if live DreamDaemon instances get set to above normal priority processes.
- `Session:LowPriorityDeploymentProcesses `: Boolean controlling if DreamMaker and API validation DreamDaemon instances get set to below normal priority processes.
- `FileLogging:Directory`: Override the default directory where server logs are stored. Default is C:/ProgramData/tgstation-server/logs on Windows, /usr/share/tgstation-server/logs otherwise
- `FileLogging:LogLevel`: Can be one of `Trace`, `Debug`, `Information`, `Warning`, `Error`, or `Critical`. Restricts what is put into the log files. Currently `Debug` is reccommended for help with error reporting.
+1 -1
View File
@@ -4,7 +4,7 @@
<Import Project="ControlPanelVersion.props" />
<PropertyGroup>
<TgsCoreVersion>4.15.6</TgsCoreVersion>
<TgsConfigVersion>4.0.0</TgsConfigVersion>
<TgsConfigVersion>4.1.0</TgsConfigVersion>
<TgsApiVersion>9.3.0</TgsApiVersion>
<TgsApiLibraryVersion>9.3.1</TgsApiLibraryVersion>
<TgsClientVersion>10.4.1</TgsClientVersion>
@@ -3,7 +3,7 @@
"isRoot": true,
"tools": {
"dotnet-ef": {
"version": "3.1.18",
"version": "3.1.20",
"commands": [
"dotnet-ef"
]
@@ -16,6 +16,7 @@ using Tgstation.Server.Host.Components.Deployment.Remote;
using Tgstation.Server.Host.Components.Events;
using Tgstation.Server.Host.Components.Repository;
using Tgstation.Server.Host.Components.Session;
using Tgstation.Server.Host.Configuration;
using Tgstation.Server.Host.Database;
using Tgstation.Server.Host.Extensions;
using Tgstation.Server.Host.IO;
@@ -93,6 +94,11 @@ namespace Tgstation.Server.Host.Components.Deployment
/// </summary>
readonly ILogger<DreamMaker> logger;
/// <summary>
/// The <see cref="SessionConfiguration"/> for <see cref="DreamMaker"/>.
/// </summary>
readonly SessionConfiguration sessionConfiguration;
/// <summary>
/// The <see cref="Instance"/> <see cref="DreamMaker"/> belongs to.
/// </summary>
@@ -147,6 +153,7 @@ namespace Tgstation.Server.Host.Components.Deployment
/// <param name="repositoryManager">The value of <see cref="repositoryManager"/>.</param>
/// <param name="remoteDeploymentManagerFactory">The value of <see cref="remoteDeploymentManagerFactory"/>.</param>
/// <param name="logger">The value of <see cref="logger"/>.</param>
/// <param name="sessionConfiguration">The value of <see cref="sessionConfiguration"/>.</param>
/// <param name="metadata">The value of <see cref="metadata"/>.</param>
public DreamMaker(
IByondManager byond,
@@ -160,6 +167,7 @@ namespace Tgstation.Server.Host.Components.Deployment
IRepositoryManager repositoryManager,
IRemoteDeploymentManagerFactory remoteDeploymentManagerFactory,
ILogger<DreamMaker> logger,
SessionConfiguration sessionConfiguration,
Api.Models.Instance metadata)
{
this.byond = byond ?? throw new ArgumentNullException(nameof(byond));
@@ -173,6 +181,7 @@ namespace Tgstation.Server.Host.Components.Deployment
this.repositoryManager = repositoryManager ?? throw new ArgumentNullException(nameof(repositoryManager));
this.remoteDeploymentManagerFactory = remoteDeploymentManagerFactory ?? throw new ArgumentNullException(nameof(remoteDeploymentManagerFactory));
this.logger = logger ?? throw new ArgumentNullException(nameof(logger));
this.sessionConfiguration = sessionConfiguration ?? throw new ArgumentNullException(nameof(sessionConfiguration));
this.metadata = metadata ?? throw new ArgumentNullException(nameof(metadata));
deploymentLock = new object();
@@ -762,6 +771,8 @@ namespace Tgstation.Server.Host.Components.Deployment
using (var provider = new TemporaryDmbProvider(ioManager.ResolvePath(job.DirectoryName.ToString()), String.Concat(job.DmeName, DmbExtension), job))
await using (var controller = await sessionControllerFactory.LaunchNew(provider, byondLock, launchParameters, true, cancellationToken).ConfigureAwait(false))
{
controller.AdjustPriority(false);
var launchResult = await controller.LaunchResult.ConfigureAwait(false);
if (launchResult.StartupTime.HasValue)
@@ -823,6 +834,10 @@ namespace Tgstation.Server.Host.Components.Deployment
true,
true,
true);
if (sessionConfiguration.LowPriorityDeploymentProcesses)
dm.AdjustPriority(false);
int exitCode;
using (cancellationToken.Register(() => dm.Terminate()))
exitCode = await dm.Lifetime.ConfigureAwait(false);
@@ -144,6 +144,12 @@ namespace Tgstation.Server.Host.Components
/// </summary>
readonly GeneralConfiguration generalConfiguration;
/// <summary>
/// The <see cref="SessionConfiguration"/> for the <see cref="InstanceFactory"/>.
/// </summary>
readonly SessionConfiguration sessionConfiguration;
#pragma warning disable CA1502 // TODO: Decomplexify
/// <summary>
/// Initializes a new instance of the <see cref="InstanceFactory"/> class.
/// </summary>
@@ -170,6 +176,7 @@ namespace Tgstation.Server.Host.Components
/// <param name="gitRemoteFeaturesFactory">The value of <see cref="gitRemoteFeaturesFactory"/>.</param>
/// <param name="remoteDeploymentManagerFactory">The value of <see cref="remoteDeploymentManagerFactory"/>.</param>
/// <param name="generalConfigurationOptions">The <see cref="IOptions{TOptions}"/> containing the value of <see cref="generalConfiguration"/>.</param>
/// <param name="sessionConfigurationOptions">The <see cref="IOptions{TOptions}"/> containing the value of <see cref="sessionConfiguration"/>.</param>
public InstanceFactory(
IIOManager ioManager,
IDatabaseContextFactory databaseContextFactory,
@@ -193,7 +200,8 @@ namespace Tgstation.Server.Host.Components
IFileTransferTicketProvider fileTransferService,
IGitRemoteFeaturesFactory gitRemoteFeaturesFactory,
IRemoteDeploymentManagerFactory remoteDeploymentManagerFactory,
IOptions<GeneralConfiguration> generalConfigurationOptions)
IOptions<GeneralConfiguration> generalConfigurationOptions,
IOptions<SessionConfiguration> sessionConfigurationOptions)
{
this.ioManager = ioManager ?? throw new ArgumentNullException(nameof(ioManager));
this.databaseContextFactory = databaseContextFactory ?? throw new ArgumentNullException(nameof(databaseContextFactory));
@@ -218,7 +226,9 @@ namespace Tgstation.Server.Host.Components
this.gitRemoteFeaturesFactory = gitRemoteFeaturesFactory ?? throw new ArgumentNullException(nameof(gitRemoteFeaturesFactory));
this.remoteDeploymentManagerFactory = remoteDeploymentManagerFactory ?? throw new ArgumentNullException(nameof(remoteDeploymentManagerFactory));
generalConfiguration = generalConfigurationOptions?.Value ?? throw new ArgumentNullException(nameof(generalConfigurationOptions));
sessionConfiguration = sessionConfigurationOptions?.Value ?? throw new ArgumentNullException(nameof(sessionConfigurationOptions));
}
#pragma warning restore CA1502
/// <inheritdoc />
#pragma warning disable CA1506 // TODO: Decomplexify
@@ -276,6 +286,7 @@ namespace Tgstation.Server.Host.Components
eventConsumer,
loggerFactory,
loggerFactory.CreateLogger<SessionControllerFactory>(),
sessionConfiguration,
metadata);
var dmbFactory = new DmbFactory(
@@ -320,6 +331,7 @@ namespace Tgstation.Server.Host.Components
repoManager,
remoteDeploymentManagerFactory,
loggerFactory.CreateLogger<DreamMaker>(),
sessionConfiguration,
metadata);
instance = new Instance(
@@ -590,7 +590,7 @@ namespace Tgstation.Server.Host.Components.Session
}
/// <inheritdoc />
public void SetHighPriority() => process.SetHighPriority();
public void AdjustPriority(bool higher) => process.AdjustPriority(higher);
/// <inheritdoc />
public void Suspend() => process.Suspend();
@@ -17,6 +17,7 @@ using Tgstation.Server.Host.Components.Deployment;
using Tgstation.Server.Host.Components.Events;
using Tgstation.Server.Host.Components.Interop;
using Tgstation.Server.Host.Components.Interop.Bridge;
using Tgstation.Server.Host.Configuration;
using Tgstation.Server.Host.Core;
using Tgstation.Server.Host.Extensions;
using Tgstation.Server.Host.IO;
@@ -99,6 +100,11 @@ namespace Tgstation.Server.Host.Components.Session
/// </summary>
readonly ILogger<SessionControllerFactory> logger;
/// <summary>
/// The <see cref="SessionConfiguration"/> for the <see cref="SessionControllerFactory"/>.
/// </summary>
readonly SessionConfiguration sessionConfiguration;
/// <summary>
/// The <see cref="Api.Models.Instance"/> for the <see cref="SessionControllerFactory"/>.
/// </summary>
@@ -170,7 +176,8 @@ namespace Tgstation.Server.Host.Components.Session
/// <param name="serverPortProvider">The value of <see cref="serverPortProvider"/>.</param>
/// <param name="loggerFactory">The value of <see cref="loggerFactory"/>.</param>
/// <param name="logger">The value of <see cref="logger"/>.</param>
/// <param name="eventConsumer">The value of <see cref="EventConsumer"/>.</param>
/// <param name="sessionConfiguration">The value of <see cref="sessionConfiguration"/>.</param>
/// <param name="eventConsumer">The value of <see cref="eventConsumer"/>.</param>
public SessionControllerFactory(
IProcessExecutor processExecutor,
IByondManager byond,
@@ -183,9 +190,10 @@ namespace Tgstation.Server.Host.Components.Session
IPlatformIdentifier platformIdentifier,
IBridgeRegistrar bridgeRegistrar,
IServerPortProvider serverPortProvider,
EventConsumer eventConsumer,
IEventConsumer eventConsumer,
ILoggerFactory loggerFactory,
ILogger<SessionControllerFactory> logger,
SessionConfiguration sessionConfiguration,
Api.Models.Instance instance)
{
this.processExecutor = processExecutor ?? throw new ArgumentNullException(nameof(processExecutor));
@@ -193,7 +201,6 @@ namespace Tgstation.Server.Host.Components.Session
this.topicClientFactory = topicClientFactory ?? throw new ArgumentNullException(nameof(topicClientFactory));
this.cryptographySuite = cryptographySuite ?? throw new ArgumentNullException(nameof(cryptographySuite));
this.assemblyInformationProvider = assemblyInformationProvider ?? throw new ArgumentNullException(nameof(assemblyInformationProvider));
this.instance = instance ?? throw new ArgumentNullException(nameof(instance));
this.ioManager = ioManager ?? throw new ArgumentNullException(nameof(ioManager));
this.chat = chat ?? throw new ArgumentNullException(nameof(chat));
this.networkPromptReaper = networkPromptReaper ?? throw new ArgumentNullException(nameof(networkPromptReaper));
@@ -203,6 +210,8 @@ namespace Tgstation.Server.Host.Components.Session
this.eventConsumer = eventConsumer ?? throw new ArgumentNullException(nameof(eventConsumer));
this.loggerFactory = loggerFactory ?? throw new ArgumentNullException(nameof(loggerFactory));
this.logger = logger ?? throw new ArgumentNullException(nameof(logger));
this.sessionConfiguration = sessionConfiguration ?? throw new ArgumentNullException(nameof(sessionConfiguration));
this.instance = instance ?? throw new ArgumentNullException(nameof(instance));
}
/// <inheritdoc />
@@ -380,6 +389,14 @@ namespace Tgstation.Server.Host.Components.Session
false,
apiValidate);
if (apiValidate)
{
if (sessionConfiguration.HighPriorityLiveDreamDaemon)
process.AdjustPriority(true);
}
else if (sessionConfiguration.LowPriorityDeploymentProcesses)
process.AdjustPriority(false);
// If this isnt a staging DD (From a Deployment), fire off an event
if (!apiValidate)
await eventConsumer.HandleEvent(
@@ -247,8 +247,7 @@ namespace Tgstation.Server.Host.Components.Watchdog
return;
}
Server.SetHighPriority();
// Server.AdjustPriority(true);
if (!reattachInProgress)
await SessionPersistor.Save(Server.ReattachInformation, cancellationToken).ConfigureAwait(false);
@@ -0,0 +1,28 @@
namespace Tgstation.Server.Host.Configuration
{
/// <summary>
/// Configuration options for the game sessions.
/// </summary>
sealed class SessionConfiguration
{
/// <summary>
/// The key for the <see cref="Microsoft.Extensions.Configuration.IConfigurationSection"/> the <see cref="SessionConfiguration"/> resides in.
/// </summary>
public const string Section = "Session";
/// <summary>
/// The default value for <see cref="HighPriorityLiveDreamDaemon"/>.
/// </summary>
private const bool DefaultHighPriorityLiveDreamDaemon = true;
/// <summary>
/// If the public DreamDaemon instances are set to be above normal priority processes.
/// </summary>
public bool HighPriorityLiveDreamDaemon { get; set; } = DefaultHighPriorityLiveDreamDaemon;
/// <summary>
/// If the deployment DreamMaker and DreamDaemon instances are set to be below normal priority processes.
/// </summary>
public bool LowPriorityDeploymentProcesses { get; set; }
}
}
@@ -120,6 +120,7 @@ namespace Tgstation.Server.Host.Core
services.UseStandardConfig<UpdatesConfiguration>(Configuration);
services.UseStandardConfig<ControlPanelConfiguration>(Configuration);
services.UseStandardConfig<SwarmConfiguration>(Configuration);
services.UseStandardConfig<SessionConfiguration>(Configuration);
// enable options which give us config reloading
services.AddOptions();
@@ -14,9 +14,10 @@ namespace Tgstation.Server.Host.System
Task<int> Lifetime { get; }
/// <summary>
/// Set's the owned <see cref="global::System.Diagnostics.Process.PriorityClass"/> to <see cref="global::System.Diagnostics.ProcessPriorityClass.AboveNormal"/>.
/// Set's the owned <see cref="global::System.Diagnostics.Process.PriorityClass"/> to a non-normal value.
/// </summary>
void SetHighPriority();
/// <param name="higher">If <see langword="true"/> will be set to <see cref="global::System.Diagnostics.ProcessPriorityClass.AboveNormal"/> otherwise, will be set to <see cref="global::System.Diagnostics.ProcessPriorityClass.BelowNormal"/>.</param>
void AdjustPriority(bool higher);
/// <summary>
/// Suspends the process.
+6 -5
View File
@@ -184,16 +184,17 @@ namespace Tgstation.Server.Host.System
}
/// <inheritdoc />
public void SetHighPriority()
public void AdjustPriority(bool higher)
{
var targetPriority = higher ? ProcessPriorityClass.AboveNormal : ProcessPriorityClass.BelowNormal;
try
{
handle.PriorityClass = ProcessPriorityClass.AboveNormal;
logger.LogTrace("Set PID {0} to above normal priority", Id);
handle.PriorityClass = targetPriority;
logger.LogTrace("Set PID {pid} to {targetPriority} priority", Id, targetPriority);
}
catch (Exception e)
catch (Exception ex)
{
logger.LogWarning(e, "Unable to raise process priority for PID {0}!", Id);
logger.LogWarning(ex, "Unable to set priority for PID {id} to {targetPriority}!", Id, targetPriority);
}
}
@@ -69,25 +69,25 @@
<PackageReference Include="Elastic.CommonSchema.Serilog" Version="1.5.3" />
<PackageReference Include="GitLabApiClient" Version="1.8.0" />
<PackageReference Include="LibGit2Sharp" Version="0.27.0-preview-0119" />
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="3.1.18" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="3.1.18" />
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="3.1.20" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="3.1.20" />
<PackageReference Include="Microsoft.CodeAnalysis.NetAnalyzers" Version="5.0.3">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="3.1.18" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="3.1.18">
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="3.1.20" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="3.1.20">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="3.1.18" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="3.1.20" />
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="3.1.18" />
<PackageReference Include="Mono.Posix.NETStandard" Version="1.0.0" />
<PackageReference Include="NetEscapades.Configuration.Yaml" Version="2.1.0" />
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="3.1.11" />
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="3.1.18" />
<PackageReference Include="Octokit" Version="0.50.0" />
<PackageReference Include="Pomelo.EntityFrameworkCore.MySql" Version="3.2.6" />
<PackageReference Include="Remora.Discord" Version="3.0.71" />
<PackageReference Include="Pomelo.EntityFrameworkCore.MySql" Version="3.2.7" />
<PackageReference Include="Remora.Discord" Version="3.0.72" />
<PackageReference Include="Serilog.Extensions.Logging" Version="3.0.1" />
<PackageReference Include="Serilog.Sinks.Async" Version="1.5.0" />
<PackageReference Include="Serilog.Sinks.Console" Version="4.0.0" />
@@ -97,13 +97,13 @@
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.1.5" />
<PackageReference Include="Swashbuckle.AspNetCore.Newtonsoft" Version="6.1.5" />
<PackageReference Include="System.Data.SqlClient" Version="4.8.2" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.2.3" />
<PackageReference Include="Swashbuckle.AspNetCore.Newtonsoft" Version="6.2.3" />
<PackageReference Include="System.Data.SqlClient" Version="4.8.3" />
<PackageReference Include="System.DirectoryServices.AccountManagement" Version="5.0.0" />
<PackageReference Include="System.IdentityModel.Tokens.Jwt" Version="6.12.2" />
<PackageReference Include="System.IdentityModel.Tokens.Jwt" Version="6.13.1" />
<PackageReference Include="System.Management" Version="5.0.0" />
<PackageReference Include="Z.EntityFramework.Plus.EFCore" Version="3.2.2" />
<PackageReference Include="Z.EntityFramework.Plus.EFCore" Version="3.2.16" />
</ItemGroup>
<ItemGroup>
@@ -11,6 +11,9 @@ General:
InstanceLimit: 10
ValidInstancePaths:
HostApiDocumentation: false
Session:
HighPriorityLiveDreamDaemon: false
LowPriorityDeploymentProcesses: true
FileLogging:
Directory:
Disable: false