mirror of
https://github.com/JustArchiNET/ArchiSteamFarm.git
synced 2026-01-01 06:00:46 +00:00
Add extra synchronization to IPC state management
Thanks @ezhevita
This commit is contained in:
@@ -355,8 +355,8 @@ public static class ASF {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ArchiLogger.LogGenericInfo(Strings.IPCConfigChanged);
|
ArchiLogger.LogGenericInfo(Strings.IPCConfigChanged);
|
||||||
await ArchiKestrel.Stop().ConfigureAwait(false);
|
|
||||||
await ArchiKestrel.Start().ConfigureAwait(false);
|
await ArchiKestrel.Restart().ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static async Task OnChangedFile(string name, string fullPath) {
|
private static async Task OnChangedFile(string name, string fullPath) {
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ using System.Net;
|
|||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Text.Json;
|
using System.Text.Json;
|
||||||
using System.Text.Json.Nodes;
|
using System.Text.Json.Nodes;
|
||||||
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using ArchiSteamFarm.Core;
|
using ArchiSteamFarm.Core;
|
||||||
using ArchiSteamFarm.Helpers.Json;
|
using ArchiSteamFarm.Helpers.Json;
|
||||||
@@ -64,6 +65,8 @@ internal static class ArchiKestrel {
|
|||||||
|
|
||||||
internal static HistoryTarget? HistoryTarget { get; private set; }
|
internal static HistoryTarget? HistoryTarget { get; private set; }
|
||||||
|
|
||||||
|
private static readonly SemaphoreSlim StateSemaphore = new(1, 1);
|
||||||
|
|
||||||
private static WebApplication? WebApplication;
|
private static WebApplication? WebApplication;
|
||||||
|
|
||||||
internal static void OnNewHistoryTarget(HistoryTarget? historyTarget = null) {
|
internal static void OnNewHistoryTarget(HistoryTarget? historyTarget = null) {
|
||||||
@@ -78,43 +81,43 @@ internal static class ArchiKestrel {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static async Task Start() {
|
internal static async Task Restart() {
|
||||||
if (WebApplication != null) {
|
await StateSemaphore.WaitAsync().ConfigureAwait(false);
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
ASF.ArchiLogger.LogGenericInfo(Strings.IPCStarting);
|
|
||||||
|
|
||||||
// Init history logger for /Api/Log usage
|
|
||||||
Logging.InitHistoryLogger();
|
|
||||||
|
|
||||||
WebApplication webApplication = await CreateWebApplication().ConfigureAwait(false);
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// Start the server
|
await StopInternally().ConfigureAwait(false);
|
||||||
await webApplication.StartAsync().ConfigureAwait(false);
|
await StartInternally().ConfigureAwait(false);
|
||||||
} catch (Exception e) {
|
} finally {
|
||||||
ASF.ArchiLogger.LogGenericException(e);
|
StateSemaphore.Release();
|
||||||
|
}
|
||||||
await webApplication.DisposeAsync().ConfigureAwait(false);
|
}
|
||||||
|
|
||||||
|
internal static async Task Start() {
|
||||||
|
if (IsRunning) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
WebApplication = webApplication;
|
await StateSemaphore.WaitAsync().ConfigureAwait(false);
|
||||||
|
|
||||||
ASF.ArchiLogger.LogGenericInfo(Strings.IPCReady);
|
try {
|
||||||
|
await StartInternally().ConfigureAwait(false);
|
||||||
|
} finally {
|
||||||
|
StateSemaphore.Release();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static async Task Stop() {
|
internal static async Task Stop() {
|
||||||
if (WebApplication == null) {
|
if (!IsRunning) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
await WebApplication.StopAsync().ConfigureAwait(false);
|
await StateSemaphore.WaitAsync().ConfigureAwait(false);
|
||||||
await WebApplication.DisposeAsync().ConfigureAwait(false);
|
|
||||||
|
|
||||||
WebApplication = null;
|
try {
|
||||||
|
await StopInternally().ConfigureAwait(false);
|
||||||
|
} finally {
|
||||||
|
StateSemaphore.Release();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[UnconditionalSuppressMessage("AssemblyLoadTrimming", "IL2026:RequiresUnreferencedCode", Justification = "PathString is a primitive, it's unlikely to be trimmed to the best of our knowledge")]
|
[UnconditionalSuppressMessage("AssemblyLoadTrimming", "IL2026:RequiresUnreferencedCode", Justification = "PathString is a primitive, it's unlikely to be trimmed to the best of our knowledge")]
|
||||||
@@ -519,4 +522,43 @@ internal static class ArchiKestrel {
|
|||||||
|
|
||||||
headers.CacheControl = cacheControl;
|
headers.CacheControl = cacheControl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static async Task StartInternally() {
|
||||||
|
if (WebApplication != null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ASF.ArchiLogger.LogGenericInfo(Strings.IPCStarting);
|
||||||
|
|
||||||
|
// Init history logger for /Api/Log usage
|
||||||
|
Logging.InitHistoryLogger();
|
||||||
|
|
||||||
|
WebApplication webApplication = await CreateWebApplication().ConfigureAwait(false);
|
||||||
|
|
||||||
|
try {
|
||||||
|
// Start the server
|
||||||
|
await webApplication.StartAsync().ConfigureAwait(false);
|
||||||
|
} catch (Exception e) {
|
||||||
|
ASF.ArchiLogger.LogGenericException(e);
|
||||||
|
|
||||||
|
await webApplication.DisposeAsync().ConfigureAwait(false);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
WebApplication = webApplication;
|
||||||
|
|
||||||
|
ASF.ArchiLogger.LogGenericInfo(Strings.IPCReady);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static async Task StopInternally() {
|
||||||
|
if (WebApplication == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
await WebApplication.StopAsync().ConfigureAwait(false);
|
||||||
|
await WebApplication.DisposeAsync().ConfigureAwait(false);
|
||||||
|
|
||||||
|
WebApplication = null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user