From caef749fa0502022c17227a83d1ba202a1dd47a8 Mon Sep 17 00:00:00 2001 From: Tamara Schmitz Date: Sun, 9 Mar 2025 16:57:59 +0100 Subject: [PATCH] hint to TaskScheduler that queue main tasks and cron tasks are long running The default TaskScheduler may also mark tasks as long running after a while and then spawn an extra thread regardless. But this way we make sure to not block the threadpool by spawning the tasks in separate threads instead in the normal pool. Also keep the denychildattach which Run would have added. See: https://devblogs.microsoft.com/pfxteam/task-run-vs-task-factory-startnew/ --- Iceshrimp.Backend/Core/Services/CronService.cs | 10 +++++----- Iceshrimp.Backend/Core/Services/QueueService.cs | 6 +++--- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/Iceshrimp.Backend/Core/Services/CronService.cs b/Iceshrimp.Backend/Core/Services/CronService.cs index 053ea130..480f64e0 100644 --- a/Iceshrimp.Backend/Core/Services/CronService.cs +++ b/Iceshrimp.Backend/Core/Services/CronService.cs @@ -67,7 +67,7 @@ file class DailyTrigger : ICronTrigger, IDisposable TriggerTime = triggerTime; CancellationToken = cancellationToken; - RunningTask = Task.Run(async () => + RunningTask = Task.Factory.StartNew(async () => { while (!CancellationToken.IsCancellationRequested) { @@ -77,7 +77,7 @@ file class DailyTrigger : ICronTrigger, IDisposable await Task.Delay(nextTrigger, CancellationToken); OnTrigger?.Invoke(); } - }, CancellationToken); + }, CancellationToken, TaskCreationOptions.DenyChildAttach | TaskCreationOptions.LongRunning, TaskScheduler.Default); } private TimeSpan TriggerTime { get; } @@ -103,14 +103,14 @@ file class IntervalTrigger : ICronTrigger, IDisposable TriggerInterval = triggerInterval; CancellationToken = cancellationToken; - RunningTask = Task.Run(async () => + RunningTask = Task.Factory.StartNew(async () => { while (!CancellationToken.IsCancellationRequested) { await Task.Delay(TriggerInterval, CancellationToken); OnTrigger?.Invoke(); } - }, CancellationToken); + }, CancellationToken, TaskCreationOptions.DenyChildAttach | TaskCreationOptions.LongRunning, TaskScheduler.Default); } private TimeSpan TriggerInterval { get; } @@ -127,4 +127,4 @@ file class IntervalTrigger : ICronTrigger, IDisposable } ~IntervalTrigger() => Dispose(); -} \ No newline at end of file +} diff --git a/Iceshrimp.Backend/Core/Services/QueueService.cs b/Iceshrimp.Backend/Core/Services/QueueService.cs index fdcce724..4274f004 100644 --- a/Iceshrimp.Backend/Core/Services/QueueService.cs +++ b/Iceshrimp.Backend/Core/Services/QueueService.cs @@ -57,8 +57,8 @@ public class QueueService( logger.LogInformation("Queue shutdown complete."); }); - _ = Task.Run(ExecuteHealthchecksWorkerAsync, token); - await Task.Run(ExecuteBackgroundWorkersAsync, tokenSource.Token); + _ = Task.Factory.StartNew(ExecuteHealthchecksWorkerAsync, token, TaskCreationOptions.DenyChildAttach | TaskCreationOptions.LongRunning, TaskScheduler.Default); + await Task.Factory.StartNew(ExecuteBackgroundWorkersAsync, tokenSource.Token, TaskCreationOptions.DenyChildAttach | TaskCreationOptions.LongRunning, TaskScheduler.Default); return; @@ -563,4 +563,4 @@ public abstract class PostgresJobQueue( await db.Jobs.Upsert(job).On(j => j.Mutex!).NoUpdate().RunAsync(); RaiseJobDelayedEvent(); } -} \ No newline at end of file +}