Async task OnUpdate (#355)

* Make OnUpdate a task instead a void, handle OnUpdate better by running it in it's own task

* Make helper transient, resolve mod loading issues
This commit is contained in:
Jesse
2025-06-04 21:53:39 +02:00
committed by GitHub
parent a92994e50b
commit 787752b555
9 changed files with 38 additions and 61 deletions
@@ -17,10 +17,10 @@ public class DialogueCallbacks(
) )
: IOnUpdate : IOnUpdate
{ {
public bool OnUpdate(long timeSinceLastRun) public Task OnUpdate(long timeSinceLastRun)
{ {
_dialogueController.Update(); _dialogueController.Update();
return true; return Task.CompletedTask;
} }
/// <summary> /// <summary>
@@ -17,15 +17,14 @@ public class HideoutCallbacks(
{ {
private readonly HideoutConfig _hideoutConfig = _configServer.GetConfig<HideoutConfig>(); private readonly HideoutConfig _hideoutConfig = _configServer.GetConfig<HideoutConfig>();
public bool OnUpdate(long timeSinceLastRun) public Task OnUpdate(long timeSinceLastRun)
{ {
if (timeSinceLastRun > _hideoutConfig.RunIntervalSeconds) if (timeSinceLastRun > _hideoutConfig.RunIntervalSeconds)
{ {
_hideoutController.Update(); _hideoutController.Update();
return true;
} }
return false; return Task.CompletedTask;
} }
/// <summary> /// <summary>
@@ -22,15 +22,14 @@ public class InsuranceCallbacks(
{ {
private readonly InsuranceConfig _insuranceConfig = _configServer.GetConfig<InsuranceConfig>(); private readonly InsuranceConfig _insuranceConfig = _configServer.GetConfig<InsuranceConfig>();
public bool OnUpdate(long timeSinceLastRun) public Task OnUpdate(long timeSinceLastRun)
{ {
if (timeSinceLastRun > Math.Max(_insuranceConfig.RunIntervalSeconds, 1)) if (timeSinceLastRun > Math.Max(_insuranceConfig.RunIntervalSeconds, 1))
{ {
_insuranceController.ProcessReturn(); _insuranceController.ProcessReturn();
return true;
} }
return false; return Task.CompletedTask;
} }
/// <summary> /// <summary>
@@ -30,7 +30,7 @@ public class RagfairCallbacks(
return Task.CompletedTask; return Task.CompletedTask;
} }
public bool OnUpdate(long timeSinceLastRun) public Task OnUpdate(long timeSinceLastRun)
{ {
if (timeSinceLastRun > _ragfairConfig.RunIntervalSeconds) if (timeSinceLastRun > _ragfairConfig.RunIntervalSeconds)
{ {
@@ -42,11 +42,9 @@ public class RagfairCallbacks(
// Process all offers / expire offers // Process all offers / expire offers
_ragfairServer.Update(); _ragfairServer.Update();
return true;
} }
return false; return Task.CompletedTask;
} }
/// <summary> /// <summary>
@@ -22,14 +22,13 @@ public class SaveCallbacks(
_saveServer.Load(); _saveServer.Load();
} }
public bool OnUpdate(long timeSinceLastRun) public Task OnUpdate(long timeSinceLastRun)
{ {
if (timeSinceLastRun > _coreConfig.ProfileSaveIntervalInSeconds) if (timeSinceLastRun > _coreConfig.ProfileSaveIntervalInSeconds)
{ {
_saveServer.Save(); _saveServer.Save();
return true;
} }
return false; return Task.CompletedTask;
} }
} }
@@ -23,9 +23,10 @@ public class TraderCallbacks(
return Task.CompletedTask; return Task.CompletedTask;
} }
public bool OnUpdate(long _) public Task OnUpdate(long _)
{ {
return _traderController.Update(); _traderController.Update();
return Task.CompletedTask;
} }
/// <summary> /// <summary>
@@ -2,5 +2,5 @@ namespace SPTarkov.Server.Core.DI;
public interface IOnUpdate public interface IOnUpdate
{ {
bool OnUpdate(long timeSinceLastRun); Task OnUpdate(long timeSinceLastRun);
} }
@@ -15,7 +15,7 @@ using LogLevel = SPTarkov.Server.Core.Models.Spt.Logging.LogLevel;
namespace SPTarkov.Server.Core.Helpers; namespace SPTarkov.Server.Core.Helpers;
[Injectable(InjectionType.Singleton)] [Injectable]
public class BotGeneratorHelper( public class BotGeneratorHelper(
ISptLogger<BotGeneratorHelper> _logger, ISptLogger<BotGeneratorHelper> _logger,
RandomUtil _randomUtil, RandomUtil _randomUtil,
@@ -26,7 +26,7 @@ public class BotGeneratorHelper(
ProfileActivityService _profileActivityService, ProfileActivityService _profileActivityService,
LocalisationService _localisationService, LocalisationService _localisationService,
ConfigServer _configServer ConfigServer _configServer
) : IOnLoad )
{ {
// Equipment slot ids that do not conflict with other slots // Equipment slot ids that do not conflict with other slots
private static readonly FrozenSet<string> _slotsWithNoCompatIssues = [ private static readonly FrozenSet<string> _slotsWithNoCompatIssues = [
@@ -37,16 +37,7 @@ public class BotGeneratorHelper(
EquipmentSlots.ArmBand.ToString() EquipmentSlots.ArmBand.ToString()
]; ];
private BotConfig _botConfig; private readonly BotConfig _botConfig = _configServer.GetConfig<BotConfig>();
private string[] _pmcTypes;
public Task OnLoad()
{
_botConfig = _configServer.GetConfig<BotConfig>();
var pmcConfig = _configServer.GetConfig<PmcConfig>();
_pmcTypes = [pmcConfig.UsecType.ToLower(), pmcConfig.BearType.ToLower()];
return Task.CompletedTask;
}
/// <summary> /// <summary>
/// Adds properties to an item /// Adds properties to an item
@@ -529,7 +520,11 @@ public class BotGeneratorHelper(
/// <returns>Equipment role (e.g. pmc / assault / bossTagilla)</returns> /// <returns>Equipment role (e.g. pmc / assault / bossTagilla)</returns>
public string GetBotEquipmentRole(string botRole) public string GetBotEquipmentRole(string botRole)
{ {
return _pmcTypes.Contains(botRole, StringComparer.OrdinalIgnoreCase) PmcConfig pmcConfig = _configServer.GetConfig<PmcConfig>();
string[] pmcTypes = [ pmcConfig.UsecType.ToLower(), pmcConfig.BearType.ToLower() ];
return pmcTypes.Contains(botRole, StringComparer.OrdinalIgnoreCase)
? Sides.PmcEquipmentRole ? Sides.PmcEquipmentRole
: botRole; : botRole;
} }
+16 -30
View File
@@ -1,3 +1,4 @@
using Microsoft.Extensions.DependencyInjection;
using SPTarkov.DI.Annotations; using SPTarkov.DI.Annotations;
using SPTarkov.Server.Core.DI; using SPTarkov.Server.Core.DI;
using SPTarkov.Server.Core.Helpers; using SPTarkov.Server.Core.Helpers;
@@ -20,6 +21,7 @@ public class App(
EncodingUtil _encodingUtil, EncodingUtil _encodingUtil,
HttpServer _httpServer, HttpServer _httpServer,
DatabaseService _databaseService, DatabaseService _databaseService,
IHostApplicationLifetime _appLifeTime,
IEnumerable<IOnLoad> _onLoadComponents, IEnumerable<IOnLoad> _onLoadComponents,
IEnumerable<IOnUpdate> _onUpdateComponents, IEnumerable<IOnUpdate> _onUpdateComponents,
HttpServerHelper _httpServerHelper HttpServerHelper _httpServerHelper
@@ -27,7 +29,6 @@ public class App(
{ {
protected CoreConfig _coreConfig = _configServer.GetConfig<CoreConfig>(); protected CoreConfig _coreConfig = _configServer.GetConfig<CoreConfig>();
protected Dictionary<string, long> _onUpdateLastRun = new(); protected Dictionary<string, long> _onUpdateLastRun = new();
protected Timer _timer;
public async Task InitializeAsync() public async Task InitializeAsync()
{ {
@@ -69,7 +70,8 @@ public class App(
await onLoad.OnLoad(); await onLoad.OnLoad();
} }
_timer = new Timer(_ => Update(_onUpdateComponents), null, TimeSpan.Zero, TimeSpan.FromMilliseconds(5000)); // Discard here, as this task will run indefinitely
_ = Task.Run(Update);
} }
public async Task StartAsync() public async Task StartAsync()
@@ -95,17 +97,20 @@ public class App(
return _localisationService.GetText("server_start_success"); return _localisationService.GetText("server_start_success");
} }
protected void Update(IEnumerable<IOnUpdate> onUpdateComponents) protected async Task Update()
{ {
try while (!_appLifeTime.ApplicationStopping.IsCancellationRequested)
{ {
// If the server has failed to start, skip any update calls // If the server has failed to start, skip any update calls
if (!_httpServer.IsStarted() || !_databaseService.IsDatabaseValid()) if (!_httpServer.IsStarted() || !_databaseService.IsDatabaseValid())
{ {
return; await Task.Delay(5000, _appLifeTime.ApplicationStopping);
// Skip forward to the next loop
continue;
} }
foreach (var updateable in onUpdateComponents) foreach (var updateable in _onUpdateComponents)
{ {
var updateableName = updateable.GetType().FullName; var updateableName = updateable.GetType().FullName;
if (string.IsNullOrEmpty(updateableName)) if (string.IsNullOrEmpty(updateableName))
@@ -113,7 +118,6 @@ public class App(
updateableName = $"{updateable.GetType().Namespace}.{updateable.GetType().Name}"; updateableName = $"{updateable.GetType().Namespace}.{updateable.GetType().Name}";
} }
var success = false;
if (!_onUpdateLastRun.TryGetValue(updateableName, out var lastRunTimeTimestamp)) if (!_onUpdateLastRun.TryGetValue(updateableName, out var lastRunTimeTimestamp))
{ {
lastRunTimeTimestamp = 0; lastRunTimeTimestamp = 0;
@@ -123,36 +127,18 @@ public class App(
try try
{ {
success = updateable.OnUpdate(secondsSinceLastRun); await updateable.OnUpdate(secondsSinceLastRun);
} }
catch (Exception err) catch (Exception err)
{ {
LogUpdateException(err, updateable); LogUpdateException(err, updateable);
} }
if (success) // Set last run after try catch, so if an exception is caused the task is seen as failed.
{ _onUpdateLastRun[updateableName] = _timeUtil.GetTimeStamp();
_onUpdateLastRun[updateableName] = _timeUtil.GetTimeStamp();
}
else
{
/* temporary for debug */
const int warnTime = 20 * 60;
if (secondsSinceLastRun % warnTime == 0)
{
if (_logger.IsLogEnabled(LogLevel.Debug))
{
_logger.Debug(_localisationService.GetText("route_onupdate_no_response", updateableName));
}
}
}
} }
}
catch (Exception e) await Task.Delay(5000, _appLifeTime.ApplicationStopping);
{
Console.WriteLine(e);
throw;
} }
} }