diff --git a/src/Tgstation.Server.Api/ApiHeaders.cs b/src/Tgstation.Server.Api/ApiHeaders.cs
index 69d6fa32e6..3758ec9b34 100644
--- a/src/Tgstation.Server.Api/ApiHeaders.cs
+++ b/src/Tgstation.Server.Api/ApiHeaders.cs
@@ -62,7 +62,7 @@ namespace Tgstation.Server.Api
public static readonly Version Version = AssemblyName.Version.Semver();
///
- /// The being accessed
+ /// The instance being accessed
///
public long? InstanceId { get; set; }
@@ -255,7 +255,7 @@ namespace Tgstation.Server.Api
/// Set using the . This initially clears
///
/// The to set
- /// The for the request
+ /// The instance for the request
public void SetRequestHeaders(HttpRequestHeaders headers, long? instanceId = null)
{
if (headers == null)
diff --git a/src/Tgstation.Server.Api/Models/EntityId.cs b/src/Tgstation.Server.Api/Models/EntityId.cs
index bf9ce0883f..85d5cd0487 100644
--- a/src/Tgstation.Server.Api/Models/EntityId.cs
+++ b/src/Tgstation.Server.Api/Models/EntityId.cs
@@ -1,7 +1,7 @@
namespace Tgstation.Server.Api.Models
{
///
- /// Common base of s and s.
+ /// Common base of s, s, and s.
///
public class EntityId
{
diff --git a/src/Tgstation.Server.Api/Models/Instance.cs b/src/Tgstation.Server.Api/Models/Instance.cs
index d3f1a78115..60856b07ea 100644
--- a/src/Tgstation.Server.Api/Models/Instance.cs
+++ b/src/Tgstation.Server.Api/Models/Instance.cs
@@ -6,13 +6,8 @@ namespace Tgstation.Server.Api.Models
///
/// Metadata about a server instance
///
- public class Instance
+ public class Instance : EntityId
{
- ///
- /// The id of the . Not modifiable
- ///
- public long Id { get; set; }
-
///
/// The name of the
///
diff --git a/src/Tgstation.Server.Client/ApiClient.cs b/src/Tgstation.Server.Client/ApiClient.cs
index b9443b8897..69d7d0f79a 100644
--- a/src/Tgstation.Server.Client/ApiClient.cs
+++ b/src/Tgstation.Server.Client/ApiClient.cs
@@ -138,7 +138,7 @@ namespace Tgstation.Server.Client
/// The route to run
/// The body of the request
/// The method of the request
- /// The optional for the request
+ /// The optional instance for the request
/// If this is a token refresh operation.
/// The for the operation
/// A resulting in the response on success
diff --git a/src/Tgstation.Server.Client/IApiClient.cs b/src/Tgstation.Server.Client/IApiClient.cs
index ab833b1731..b1c8519892 100644
--- a/src/Tgstation.Server.Client/IApiClient.cs
+++ b/src/Tgstation.Server.Client/IApiClient.cs
@@ -105,7 +105,7 @@ namespace Tgstation.Server.Client
/// The type of the response body
/// The server route to make the request to
/// The request body
- /// The to make the request to
+ /// The instance to make the request to
/// The for the operation
/// A resulting in the response body as a
Task Create(string route, TBody body, long instanceId, CancellationToken cancellationToken);
@@ -115,7 +115,7 @@ namespace Tgstation.Server.Client
///
/// The type of the response body
/// The server route to make the request to
- /// The to make the request to
+ /// The instance to make the request to
/// The for the operation
/// A resulting in the response body as a
Task Create(string route, long instanceId, CancellationToken cancellationToken);
@@ -125,7 +125,7 @@ namespace Tgstation.Server.Client
///
/// The type of the response body
/// The server route to make the request to
- /// The to make the request to
+ /// The instance to make the request to
/// The for the operation
/// A resulting in the response body as a
Task Patch(string route, long instanceId, CancellationToken cancellationToken);
@@ -135,7 +135,7 @@ namespace Tgstation.Server.Client
///
/// The type of the response body
/// The server route to make the request to
- /// The to make the request to
+ /// The instance to make the request to
/// The for the operation
/// A resulting in the response body as a
Task Read(string route, long instanceId, CancellationToken cancellationToken);
@@ -147,7 +147,7 @@ namespace Tgstation.Server.Client
/// The type of the response body
/// The server route to make the request to
/// The request body
- /// The to make the request to
+ /// The instance to make the request to
/// The for the operation
/// A resulting in the response body as a
Task Update(string route, TBody body, long instanceId, CancellationToken cancellationToken);
@@ -156,7 +156,7 @@ namespace Tgstation.Server.Client
/// Run an HTTP DELETE request
///
/// The server route to make the request to
- /// The to make the request to
+ /// The instance to make the request to
/// The for the operation
/// A representing the running operation
Task Delete(string route, long instanceId, CancellationToken cancellationToken);
@@ -167,7 +167,7 @@ namespace Tgstation.Server.Client
/// The type to of the request body
/// The server route to make the request to
/// The request body
- /// The to make the request to
+ /// The instance to make the request to
/// The for the operation
/// A representing the running operation
Task Delete(string route, TBody body, long instanceId, CancellationToken cancellationToken);
@@ -177,7 +177,7 @@ namespace Tgstation.Server.Client
///
/// The type of the response body
/// The server route to make the request to
- /// The to make the request to
+ /// The instance to make the request to
/// The for the operation
/// A resulting in the response body as a
Task Delete(string route, long instanceId, CancellationToken cancellationToken);
diff --git a/src/Tgstation.Server.Client/IInstanceManagerClient.cs b/src/Tgstation.Server.Client/IInstanceManagerClient.cs
index 73d60a3893..57030b1deb 100644
--- a/src/Tgstation.Server.Client/IInstanceManagerClient.cs
+++ b/src/Tgstation.Server.Client/IInstanceManagerClient.cs
@@ -21,7 +21,7 @@ namespace Tgstation.Server.Client
///
/// Create or attach an
///
- /// The to create. will be ignored
+ /// The to create. will be ignored
/// The for the operation
/// A resulting in the created or attached
Task CreateOrAttach(Instance instance, CancellationToken cancellationToken);
diff --git a/src/Tgstation.Server.Host/Components/Chat/ChatManager.cs b/src/Tgstation.Server.Host/Components/Chat/ChatManager.cs
index dd4caa7835..8a6a3c0071 100644
--- a/src/Tgstation.Server.Host/Components/Chat/ChatManager.cs
+++ b/src/Tgstation.Server.Host/Components/Chat/ChatManager.cs
@@ -1,5 +1,6 @@
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
+using Serilog.Context;
using System;
using System.Collections.Generic;
using System.Globalization;
@@ -111,6 +112,11 @@ namespace Tgstation.Server.Host.Components.Chat
///
ulong channelIdCounter;
+ ///
+ /// The number of s processed.
+ ///
+ long messagesProcessed;
+
///
/// If has been called
///
@@ -407,7 +413,9 @@ namespace Tgstation.Server.Host.Components.Chat
foreach (var I in messageTasks.Where(x => x.Value.IsCompleted).ToList())
{
var message = await I.Value.ConfigureAwait(false);
- await ProcessMessage(I.Key, message, cancellationToken).ConfigureAwait(false);
+ var messageNumber = Interlocked.Increment(ref messagesProcessed);
+ using (LogContext.PushProperty("ChatMessage", messageNumber))
+ await ProcessMessage(I.Key, message, cancellationToken).ConfigureAwait(false);
messageTasks.Remove(I.Key);
}
}
diff --git a/src/Tgstation.Server.Host/Components/Chat/Message.cs b/src/Tgstation.Server.Host/Components/Chat/Message.cs
index 24e18962e4..5f661fd4f7 100644
--- a/src/Tgstation.Server.Host/Components/Chat/Message.cs
+++ b/src/Tgstation.Server.Host/Components/Chat/Message.cs
@@ -11,7 +11,7 @@
public string Content { get; set; }
///
- /// The who sent the
+ /// The who sent the
///
public ChatUser User { get; set; }
}
diff --git a/src/Tgstation.Server.Host/Components/IInstance.cs b/src/Tgstation.Server.Host/Components/IInstance.cs
index ee975d13a8..475c625482 100644
--- a/src/Tgstation.Server.Host/Components/IInstance.cs
+++ b/src/Tgstation.Server.Host/Components/IInstance.cs
@@ -13,7 +13,7 @@ namespace Tgstation.Server.Host.Components
///
/// For interacting with the instance services
///
- public interface IInstance : ILatestCompileJobProvider, IHostedService, IDisposable
+ public interface IInstance : ILatestCompileJobProvider, IHostedService, IRenameNotifyee, IDisposable
{
///
/// The for the
@@ -45,12 +45,6 @@ namespace Tgstation.Server.Host.Components
///
IConfiguration Configuration { get; }
- ///
- /// Rename the
- ///
- /// The new name for the
- void Rename(string newName);
-
///
/// Change the for the
///
diff --git a/src/Tgstation.Server.Host/Components/IRenameNotifyee.cs b/src/Tgstation.Server.Host/Components/IRenameNotifyee.cs
new file mode 100644
index 0000000000..d40afc0023
--- /dev/null
+++ b/src/Tgstation.Server.Host/Components/IRenameNotifyee.cs
@@ -0,0 +1,19 @@
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace Tgstation.Server.Host.Components
+{
+ ///
+ /// Handler for an instance being renamed.
+ ///
+ public interface IRenameNotifyee
+ {
+ ///
+ /// Called when the owning is renamed.
+ ///
+ /// The new .
+ /// The for the operation.
+ /// A representing the running operation.
+ Task InstanceRenamed(string newInstanceName, CancellationToken cancellationToken);
+ }
+}
diff --git a/src/Tgstation.Server.Host/Components/Instance.cs b/src/Tgstation.Server.Host/Components/Instance.cs
index 76d67ce595..62d5545faa 100644
--- a/src/Tgstation.Server.Host/Components/Instance.cs
+++ b/src/Tgstation.Server.Host/Components/Instance.cs
@@ -1,5 +1,6 @@
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;
+using Serilog.Context;
using System;
using System.Collections.Generic;
using System.Linq;
@@ -134,12 +135,15 @@ namespace Tgstation.Server.Host.Components
///
public void Dispose()
{
- timerCts?.Dispose();
- Configuration.Dispose();
- Chat.Dispose();
- Watchdog.Dispose();
- dmbFactory.Dispose();
- RepositoryManager.Dispose();
+ using (LogContext.PushProperty("Instance", metadata.Id))
+ {
+ timerCts?.Dispose();
+ Configuration.Dispose();
+ Chat.Dispose();
+ Watchdog.Dispose();
+ dmbFactory.Dispose();
+ RepositoryManager.Dispose();
+ }
}
///
@@ -151,7 +155,7 @@ namespace Tgstation.Server.Host.Components
#pragma warning disable CA1502 // TODO: Decomplexify
async Task TimerLoop(uint minutes, CancellationToken cancellationToken)
{
- logger.LogTrace("Entering auto-update loop");
+ logger.LogDebug("Entering auto-update loop");
while (true)
try
{
@@ -393,17 +397,20 @@ namespace Tgstation.Server.Host.Components
#pragma warning restore CA1502
///
- public void Rename(string newName)
+ public Task InstanceRenamed(string newName, CancellationToken cancellationToken)
{
if (String.IsNullOrWhiteSpace(newName))
throw new ArgumentNullException(nameof(newName));
metadata.Name = newName;
+ return Watchdog.InstanceRenamed(newName, cancellationToken);
}
///
public async Task StartAsync(CancellationToken cancellationToken)
{
- await Task.WhenAll(
+ using (LogContext.PushProperty("Instance", metadata.Id))
+ {
+ await Task.WhenAll(
SetAutoUpdateInterval(metadata.AutoUpdateInterval.Value),
Configuration.StartAsync(cancellationToken),
ByondManager.StartAsync(cancellationToken),
@@ -411,23 +418,27 @@ namespace Tgstation.Server.Host.Components
dmbFactory.StartAsync(cancellationToken))
.ConfigureAwait(false);
- // dependent on so many things, its just safer this way
- await Watchdog.StartAsync(cancellationToken).ConfigureAwait(false);
+ // dependent on so many things, its just safer this way
+ await Watchdog.StartAsync(cancellationToken).ConfigureAwait(false);
- await dmbFactory.CleanUnusedCompileJobs(cancellationToken).ConfigureAwait(false);
+ await dmbFactory.CleanUnusedCompileJobs(cancellationToken).ConfigureAwait(false);
+ }
}
///
public async Task StopAsync(CancellationToken cancellationToken)
{
- await SetAutoUpdateInterval(0).ConfigureAwait(false);
- await Watchdog.StopAsync(cancellationToken).ConfigureAwait(false);
- await Task.WhenAll(
- Configuration.StopAsync(cancellationToken),
- ByondManager.StopAsync(cancellationToken),
- Chat.StopAsync(cancellationToken),
- dmbFactory.StopAsync(cancellationToken))
- .ConfigureAwait(false);
+ using (LogContext.PushProperty("Instance", metadata.Id))
+ {
+ await SetAutoUpdateInterval(0).ConfigureAwait(false);
+ await Watchdog.StopAsync(cancellationToken).ConfigureAwait(false);
+ await Task.WhenAll(
+ Configuration.StopAsync(cancellationToken),
+ ByondManager.StopAsync(cancellationToken),
+ Chat.StopAsync(cancellationToken),
+ dmbFactory.StopAsync(cancellationToken))
+ .ConfigureAwait(false);
+ }
}
///
@@ -438,8 +449,12 @@ namespace Tgstation.Server.Host.Components
{
if (timerTask != null)
{
+ logger.LogTrace("Cancelling auto-update task");
timerCts.Cancel();
+ timerCts.Dispose();
toWait = timerTask;
+ timerTask = null;
+ timerCts = null;
}
else
toWait = Task.CompletedTask;
@@ -447,13 +462,20 @@ namespace Tgstation.Server.Host.Components
await toWait.ConfigureAwait(false);
if (newInterval == 0)
+ {
+ logger.LogTrace("New auto-update interval is 0. Not starting task.");
return;
+ }
+
lock (timerLock)
{
// race condition, just quit
if (timerTask != null)
+ {
+ logger.LogDebug("Aborting auto update interval change due to race condition!");
return;
- timerCts?.Dispose();
+ }
+
timerCts = new CancellationTokenSource();
timerTask = TimerLoop(newInterval, timerCts.Token);
}
diff --git a/src/Tgstation.Server.Host/Components/InstanceManager.cs b/src/Tgstation.Server.Host/Components/InstanceManager.cs
index 062dca8163..e0045ccbc9 100644
--- a/src/Tgstation.Server.Host/Components/InstanceManager.cs
+++ b/src/Tgstation.Server.Host/Components/InstanceManager.cs
@@ -8,6 +8,7 @@ using System.Diagnostics;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
+using Tgstation.Server.Api.Models;
using Tgstation.Server.Host.Components.Interop;
using Tgstation.Server.Host.Components.Interop.Bridge;
using Tgstation.Server.Host.Configuration;
@@ -72,7 +73,7 @@ namespace Tgstation.Server.Host.Components
readonly ILogger logger;
///
- /// Map of s to respective s. Also used as a .
+ /// Map of instance s to respective s. Also used as a .
///
readonly IDictionary instances;
diff --git a/src/Tgstation.Server.Host/Components/Interop/Bridge/IBridgeHandler.cs b/src/Tgstation.Server.Host/Components/Interop/Bridge/IBridgeHandler.cs
index 5ca5347e3d..5d262a277e 100644
--- a/src/Tgstation.Server.Host/Components/Interop/Bridge/IBridgeHandler.cs
+++ b/src/Tgstation.Server.Host/Components/Interop/Bridge/IBridgeHandler.cs
@@ -1,7 +1,4 @@
-using System.Threading;
-using System.Threading.Tasks;
-
-namespace Tgstation.Server.Host.Components.Interop.Bridge
+namespace Tgstation.Server.Host.Components.Interop.Bridge
{
///
interface IBridgeHandler : IBridgeDispatcher
@@ -10,13 +7,5 @@ namespace Tgstation.Server.Host.Components.Interop.Bridge
/// The for the .
///
DMApiParameters DMApiParameters { get; }
-
- ///
- /// Called when the owning is renamed.
- ///
- /// The new .
- /// The for the operation.
- /// A representing the running operation.
- Task InstanceRenamed(string newInstanceName, CancellationToken cancellationToken);
}
}
\ No newline at end of file
diff --git a/src/Tgstation.Server.Host/Components/Session/DeadSessionController.cs b/src/Tgstation.Server.Host/Components/Session/DeadSessionController.cs
index a49c9f7738..2f5ff7f5c4 100644
--- a/src/Tgstation.Server.Host/Components/Session/DeadSessionController.cs
+++ b/src/Tgstation.Server.Host/Components/Session/DeadSessionController.cs
@@ -120,5 +120,8 @@ namespace Tgstation.Server.Host.Components.Session
///
public void Resume() => throw new NotSupportedException();
+
+ ///
+ public Task InstanceRenamed(string newInstanceName, CancellationToken cancellationToken) => Task.CompletedTask;
}
}
diff --git a/src/Tgstation.Server.Host/Components/Session/ISessionController.cs b/src/Tgstation.Server.Host/Components/Session/ISessionController.cs
index c598d9a331..fdc9536ec5 100644
--- a/src/Tgstation.Server.Host/Components/Session/ISessionController.cs
+++ b/src/Tgstation.Server.Host/Components/Session/ISessionController.cs
@@ -10,7 +10,7 @@ namespace Tgstation.Server.Host.Components.Session
///
/// Handles communication with a DreamDaemon
///
- interface ISessionController : IProcessBase
+ interface ISessionController : IRenameNotifyee, IProcessBase
{
///
/// A that completes when DreamDaemon starts pumping the windows message queue after loading a .dmb or when it crashes
diff --git a/src/Tgstation.Server.Host/Components/Session/SessionController.cs b/src/Tgstation.Server.Host/Components/Session/SessionController.cs
index 3d1590cc4e..dca20a3a14 100644
--- a/src/Tgstation.Server.Host/Components/Session/SessionController.cs
+++ b/src/Tgstation.Server.Host/Components/Session/SessionController.cs
@@ -1,6 +1,7 @@
using Byond.TopicSender;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
+using Serilog.Context;
using System;
using System.Collections.Generic;
using System.Globalization;
@@ -105,6 +106,11 @@ namespace Tgstation.Server.Host.Components.Session
///
readonly ReattachInformation reattachInformation;
+ ///
+ /// The metadata.
+ ///
+ readonly Api.Models.Instance metadata;
+
///
/// A used for the topic send operation made on reattaching.
///
@@ -194,6 +200,7 @@ namespace Tgstation.Server.Host.Components.Session
/// Construct a
///
/// The value of
+ /// The owning .
/// The value of
/// The value of
/// The value of
@@ -206,6 +213,7 @@ namespace Tgstation.Server.Host.Components.Session
/// If this is a reattached session.
public SessionController(
ReattachInformation reattachInformation,
+ Api.Models.Instance metadata,
IProcess process,
IByondExecutableLock byondLock,
ITopicClient byondTopicSender,
@@ -218,6 +226,7 @@ namespace Tgstation.Server.Host.Components.Session
bool reattached)
{
this.reattachInformation = reattachInformation ?? throw new ArgumentNullException(nameof(reattachInformation));
+ this.metadata = metadata ?? throw new ArgumentNullException(nameof(metadata));
this.process = process ?? throw new ArgumentNullException(nameof(process));
this.byondLock = byondLock ?? throw new ArgumentNullException(nameof(byondLock));
this.byondTopicSender = byondTopicSender ?? throw new ArgumentNullException(nameof(byondTopicSender));
@@ -364,141 +373,145 @@ namespace Tgstation.Server.Host.Components.Session
if (parameters == null)
throw new ArgumentNullException(nameof(parameters));
- var response = new BridgeResponse();
- switch (parameters.CommandType)
+ using (LogContext.PushProperty("Instance", metadata.Id))
{
- case BridgeCommandType.ChatSend:
- if (parameters.ChatMessage == null)
- return new BridgeResponse
- {
- ErrorMessage = "Missing chatMessage field!"
- };
-
- if (parameters.ChatMessage.ChannelIds == null)
- return new BridgeResponse
- {
- ErrorMessage = "Missing channelIds field in chatMessage!"
- };
-
- if(parameters.ChatMessage.ChannelIds.Any(channelIdString => !UInt64.TryParse(channelIdString, out var _)))
- return new BridgeResponse
- {
- ErrorMessage = "Invalid channelIds in chatMessage!"
- };
-
- if (parameters.ChatMessage.Text == null)
- return new BridgeResponse
- {
- ErrorMessage = "Missing message field in chatMessage!"
- };
-
- await chat.SendMessage(
- parameters.ChatMessage.Text,
- parameters.ChatMessage.ChannelIds.Select(UInt64.Parse),
- cancellationToken).ConfigureAwait(false);
- break;
- case BridgeCommandType.Prime:
- var oldPrimeTcs = primeTcs;
- primeTcs = new TaskCompletionSource