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:
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user