Cleanup interop a bit

This commit is contained in:
Jordan Brown
2018-08-07 11:25:45 -04:00
parent 77e1633866
commit 98b19792d8
6 changed files with 55 additions and 18 deletions
+8 -2
View File
@@ -47,14 +47,14 @@
#define TGS_EVENT_PORT_SWAP -2 //before a port change is about to happen, extra parameter is new port
#define TGS_EVENT_REBOOT_MODE_CHANGE -1 //before a reboot mode change, extras parameters are the current and new reboot mode enums
//TODO
//OTHER ENUMS
#define TGS_REBOOT_MODE_NORMAL 0
#define TGS_REBOOT_MODE_SHUTDOWN 1
#define TGS_REBOOT_MODE_RESTART 2
//TODO
//REQUIRED HOOKS
//Call this somewhere in /world/New() that is always run
@@ -74,6 +74,12 @@
/world/proc/TgsReboot()
return
//OPTIONAL HOOKS
//called with debug messages
/world/proc/TgsDebug(message)
return
//DATUM DEFINITIONS
//unless otherwise specified all datums defined here should be considered read-only, warranty void if written
@@ -178,10 +178,12 @@ namespace Tgstation.Server.Host.Components
var tasks = new List<Task>();
await dbInstances.ForEachAsync(metadata => tasks.Add(metadata.Online.Value ? OnlineInstance(metadata, cancellationToken) : Task.CompletedTask), cancellationToken).ConfigureAwait(false);
await Task.WhenAll(tasks).ConfigureAwait(false);
logger.LogInformation("Instance manager ready!");
application.Ready(null);
}
catch (Exception e)
{
logger.LogCritical("Instance manager startup error! Exception: {0}", e);
application.Ready(e);
}
});
@@ -1,11 +1,12 @@
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using Microsoft.Net.Http.Headers;
using System;
using System.Linq;
using System.Net.Http.Headers;
using System.Threading;
using System.Threading.Tasks;
using Tgstation.Server.Host.Components;
using Tgstation.Server.Host.Models;
using Tgstation.Server.Host.Security;
namespace Tgstation.Server.Host.Controllers
{
@@ -13,23 +14,27 @@ namespace Tgstation.Server.Host.Controllers
/// Handles requests from DreamDaemon
/// </summary>
[Route("/Interop")]
public sealed class InteropController : ApiController
public sealed class InteropController : Controller
{
/// <summary>
/// The <see cref="IInstanceManager"/> for the <see cref="InteropController"/>
/// </summary>
readonly IInstanceManager instanceManager;
/// <summary>
/// The <see cref="ILogger"/> for the <see cref="InteropController"/>
/// </summary>
readonly ILogger<InteropController> logger;
/// <summary>
/// Construct an <see cref="InteropController"/>
/// </summary>
/// <param name="databaseContext">The <see cref="IDatabaseContext"/> for the <see cref="ApiController"/></param>
/// <param name="authenticationContextFactory">The <see cref="IAuthenticationContextFactory"/> for the <see cref="ApiController"/></param>
/// <param name="instanceManager">The value of <see cref="instanceManager"/></param>
/// <param name="logger">The <see cref="ILogger"/> for the <see cref="ApiController"/></param>
public InteropController(IInstanceManager instanceManager, IDatabaseContext databaseContext, IAuthenticationContextFactory authenticationContextFactory, ILogger<InteropController> logger) : base(databaseContext, authenticationContextFactory, logger, false)
/// <param name="logger">The value of <see cref="logger"/></param>
public InteropController(IInstanceManager instanceManager, ILogger<InteropController> logger)
{
this.instanceManager = instanceManager ?? throw new ArgumentNullException(nameof(instanceManager));
this.logger = logger ?? throw new ArgumentNullException(nameof(logger));
}
/// <summary>
@@ -40,6 +45,14 @@ namespace Tgstation.Server.Host.Controllers
[HttpGet]
public async Task<IActionResult> HandleInterop(CancellationToken cancellationToken)
{
//since this is the only identifying factor of a TGS server we want to pretend we don't exist unless it at least has the correct BYOND headers
if (!Request.Headers.TryGetValue(HeaderNames.UserAgent, out var userAgentValues)
|| !ProductInfoHeaderValue.TryParse(userAgentValues.FirstOrDefault(), out var clientUserAgent)
|| clientUserAgent.Product.Name != "libbyond")
return Unauthorized();
logger.LogDebug("Request from BYOND: {0}", Request.QueryString);
var result = await instanceManager.HandleWorldExport(Request.Query, cancellationToken).ConfigureAwait(false);
//explain things in very simple terms dream daemon can understand
//EXCEPT DREAMDAENEN BUGS
@@ -243,6 +243,8 @@ namespace Tgstation.Server.Host.Core
logger.LogInformation(VersionString);
logger.LogDebug("Configuring middleware...");
serverAddresses = applicationBuilder.ServerFeatures.Get<IServerAddressesFeature>();
applicationBuilder.UseDeveloperExceptionPage(); //it is not worth it to limit this, you should only ever get it if you're an authorized user
+22 -8
View File
@@ -1,6 +1,6 @@
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Linq;
@@ -17,6 +17,12 @@ namespace Tgstation.Server.Host.Core
/// The <see cref="IServiceProvider"/> for the <see cref="JobManager"/>
/// </summary>
readonly IServiceProvider serviceProvider;
/// <summary>
/// The <see cref="ILogger"/> for the <see cref="JobManager"/>
/// </summary>
readonly ILogger<JobManager> logger;
/// <summary>
/// <see cref="Dictionary{TKey, TValue}"/> of <see cref="Api.Models.Internal.Job.Id"/> to running <see cref="JobHandler"/>s
/// </summary>
@@ -26,9 +32,11 @@ namespace Tgstation.Server.Host.Core
/// Construct a <see cref="JobManager"/>
/// </summary>
/// <param name="serviceProvider">The value of <see cref="serviceProvider"/></param>
public JobManager(IServiceProvider serviceProvider)
/// <param name="logger">The value of <see cref="logger"/></param>
public JobManager(IServiceProvider serviceProvider, ILogger<JobManager> logger)
{
this.serviceProvider = serviceProvider ?? throw new ArgumentNullException(nameof(serviceProvider));
this.logger = logger ?? throw new ArgumentNullException(nameof(logger));
jobs = new Dictionary<long, JobHandler>();
}
@@ -144,20 +152,26 @@ namespace Tgstation.Server.Host.Core
/// <inheritdoc />
public async Task StartAsync(CancellationToken cancellationToken)
{
logger.LogTrace("Starting job manager...");
using (var scope = serviceProvider.CreateScope())
{
var databaseContext = scope.ServiceProvider.GetRequiredService<IDatabaseContext>();
//mark all jobs as cancelled
var enumerator = await databaseContext.Jobs.Where(y => !y.Cancelled.Value && !y.StoppedAt.HasValue).Select(y => y.Id).ToListAsync(cancellationToken).ConfigureAwait(false);
foreach(var I in enumerator)
var badJobs = await databaseContext.Jobs.Where(y => !y.Cancelled.Value && !y.StoppedAt.HasValue).Select(y => y.Id).ToListAsync(cancellationToken).ConfigureAwait(false);
if (badJobs.Count > 0)
{
var job = new Job { Id = I };
databaseContext.Jobs.Attach(job);
job.Cancelled = true;
logger.LogTrace("Cleaning {0} unfinished jobs...", badJobs.Count);
foreach (var I in enumerator)
{
var job = new Job { Id = I };
databaseContext.Jobs.Attach(job);
job.Cancelled = true;
}
await databaseContext.Save(cancellationToken).ConfigureAwait(false);
}
await databaseContext.Save(cancellationToken).ConfigureAwait(false);
}
logger.LogDebug("Job manager started!");
}
/// <inheritdoc />
+1 -1
View File
@@ -15,7 +15,7 @@
"Console": {
"LogLevel": {
"Default": "Trace",
"Microsoft": "Information"
"Microsoft": "Warning"
}
},
"LogLevel": {