From fef542512b285fb8138e06545051804e009b894f Mon Sep 17 00:00:00 2001 From: "Eric J. Smith" Date: Mon, 28 Oct 2024 16:08:00 -0500 Subject: [PATCH] Move job scheduler checks into it's own activity --- .../Jobs/HostedJobService.cs | 3 -- .../Jobs/ScheduledJobRunner.cs | 1 - .../Jobs/ScheduledJobService.cs | 32 +++++++++++-------- src/Foundatio/Jobs/IJob.cs | 2 ++ src/Foundatio/Jobs/JobRunner.cs | 2 ++ 5 files changed, 22 insertions(+), 18 deletions(-) diff --git a/src/Foundatio.Extensions.Hosting/Jobs/HostedJobService.cs b/src/Foundatio.Extensions.Hosting/Jobs/HostedJobService.cs index 7d9eca1a..ffc54dbf 100644 --- a/src/Foundatio.Extensions.Hosting/Jobs/HostedJobService.cs +++ b/src/Foundatio.Extensions.Hosting/Jobs/HostedJobService.cs @@ -1,5 +1,4 @@ using System; -using System.Diagnostics; using System.Threading; using System.Threading.Tasks; using Foundatio.Extensions.Hosting.Startup; @@ -52,8 +51,6 @@ private async Task ExecuteAsync(CancellationToken stoppingToken) try { - using var activity = FoundatioDiagnostics.ActivitySource.StartActivity("Job: " + _jobOptions.Name); - await runner.RunAsync(stoppingToken).AnyContext(); #if NET8_0_OR_GREATER await _stoppingCts.CancelAsync().AnyContext(); diff --git a/src/Foundatio.Extensions.Hosting/Jobs/ScheduledJobRunner.cs b/src/Foundatio.Extensions.Hosting/Jobs/ScheduledJobRunner.cs index 19758c5b..431cf93e 100644 --- a/src/Foundatio.Extensions.Hosting/Jobs/ScheduledJobRunner.cs +++ b/src/Foundatio.Extensions.Hosting/Jobs/ScheduledJobRunner.cs @@ -1,5 +1,4 @@ using System; -using System.Diagnostics; using System.Threading; using System.Threading.Tasks; using Foundatio.Caching; diff --git a/src/Foundatio.Extensions.Hosting/Jobs/ScheduledJobService.cs b/src/Foundatio.Extensions.Hosting/Jobs/ScheduledJobService.cs index 04441f14..d1a3dca7 100644 --- a/src/Foundatio.Extensions.Hosting/Jobs/ScheduledJobService.cs +++ b/src/Foundatio.Extensions.Hosting/Jobs/ScheduledJobService.cs @@ -1,9 +1,8 @@ using System; -using System.Diagnostics; +using System.Collections.Generic; using System.Threading; using System.Threading.Tasks; using Foundatio.Extensions.Hosting.Startup; -using Foundatio.Messaging; using Foundatio.Utility; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; @@ -14,11 +13,13 @@ public class ScheduledJobService : BackgroundService { private readonly IServiceProvider _serviceProvider; private readonly JobManager _jobManager; + private readonly TimeProvider _timeProvider; public ScheduledJobService(IServiceProvider serviceProvider, JobManager jobManager) { _serviceProvider = serviceProvider; _jobManager = jobManager; + _timeProvider = _timeProvider = serviceProvider.GetService() ?? TimeProvider.System; } protected override async Task ExecuteAsync(CancellationToken stoppingToken) @@ -33,25 +34,28 @@ protected override async Task ExecuteAsync(CancellationToken stoppingToken) } } + // delay until right after next minute starts to sync with cron schedules + await Task.Delay(TimeSpan.FromSeconds(60 - _timeProvider.GetUtcNow().UtcDateTime.Second)); + while (!stoppingToken.IsCancellationRequested) { - foreach (var jobToRun in _jobManager.Jobs) + var jobsToRun = new List(); + using (var activity = FoundatioDiagnostics.ActivitySource.StartActivity("Job Scheduler")) + { + foreach (var job in _jobManager.Jobs) + if (await job.ShouldRunAsync()) + jobsToRun.Add(job); + } + + foreach (var jobToRun in jobsToRun) { using var activity = FoundatioDiagnostics.ActivitySource.StartActivity("Job: " + jobToRun.Options.Name); - if (await jobToRun.ShouldRunAsync()) - { - await jobToRun.StartAsync(stoppingToken).AnyContext(); - } - else - { - // don't record trace if we didn't run the job and we started the root activity - if (activity is { Parent: null }) - activity.ActivityTraceFlags &= ~ActivityTraceFlags.Recorded; - } + await jobToRun.StartAsync(stoppingToken).AnyContext(); } - await Task.Delay(TimeSpan.FromSeconds(5), stoppingToken).AnyContext(); + // shortest cron schedule is 1 minute so only check every minute + await Task.Delay(TimeSpan.FromMinutes(1), stoppingToken).AnyContext(); } } } diff --git a/src/Foundatio/Jobs/IJob.cs b/src/Foundatio/Jobs/IJob.cs index cb2b9f11..3d9f171d 100644 --- a/src/Foundatio/Jobs/IJob.cs +++ b/src/Foundatio/Jobs/IJob.cs @@ -51,6 +51,8 @@ public static async Task RunContinuousAsync(this IJob job, TimeSpan? interv while (!cancellationToken.IsCancellationRequested) { + using var activity = FoundatioDiagnostics.ActivitySource.StartActivity("Job: " + jobName); + var result = await job.TryRunAsync(cancellationToken).AnyContext(); logger.LogJobResult(result, jobName); diff --git a/src/Foundatio/Jobs/JobRunner.cs b/src/Foundatio/Jobs/JobRunner.cs index 574ee786..3792db20 100644 --- a/src/Foundatio/Jobs/JobRunner.cs +++ b/src/Foundatio/Jobs/JobRunner.cs @@ -210,6 +210,8 @@ await jobInstance.RunContinuousAsync(_options.Interval, _options.IterationLimit, } else { + using var activity = FoundatioDiagnostics.ActivitySource.StartActivity("Job: " + _jobName); + var result = await job.TryRunAsync(cancellationToken).AnyContext(); _logger.LogJobResult(result, _jobName);