Code/StateManagement/Ticker.cs
using Sandbox;
using System;
using System.Threading.Tasks;
namespace SandbankDatabase;
/// <summary>
/// Polls stuff in the database at short intervals.
/// </summary>
internal static class Ticker
{
private static float _timeSinceTickedBackups = 0;
private static float _timeSinceTickedCache = 0;
private static float _timeSinceTickedPool = 0;
public static void Initialise()
{
#pragma warning disable CS1998
// It's really important that this gets its own thread. Putting it in an async task would block up the
// default worker threads, which could cause freezes if it gets in the way of user code.
GameTask.RunInThreadAsync( async () =>
{
_ = BackgroundTicker();
} );
#pragma warning restore CS1998
}
private static async Task BackgroundTicker()
{
Logging.Log( "initialising ticker..." );
var lastCheckTime = DateTime.UtcNow;
while ( InitialisationController.CurrentDatabaseState == DatabaseState.Initialised )
{
if ( !Game.IsPlaying && !TestHelpers.IsUnitTests )
{
lock ( InitialisationController.DatabaseStateLock )
{
InitialisationController.CurrentDatabaseState = DatabaseState.ShuttingDown;
break;
}
}
if ( _timeSinceTickedBackups >= 10 )
{
_timeSinceTickedBackups = 0;
TickBackups();
}
if ( _timeSinceTickedCache >= ConfigController.TICK_DELTA )
{
_timeSinceTickedCache = 0;
TickCache();
}
if ( _timeSinceTickedPool >= 1 )
{
_timeSinceTickedPool = 0;
TickPool();
}
await Task.Delay( 100 );
// TimeSince does not work at all. So let's do it manually.
var difference = (float)(DateTime.UtcNow - lastCheckTime).TotalSeconds;
_timeSinceTickedPool += difference;
_timeSinceTickedCache += difference;
_timeSinceTickedBackups += difference;
lastCheckTime = DateTime.UtcNow;
}
// Try and shut down the database.
ShutdownController.ShutdownDatabase();
}
private static void TickBackups()
{
Backups.CheckBackupStatus();
}
private static void TickCache()
{
Cache.Tick();
}
private static void TickPool()
{
ObjectPool.CheckPool();
}
}