Skip to content

Commit 4828d7a

Browse files
Sync changes from main to net8 - Applied recent commits, updated versions & framework, preserved .csproj files (#342)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
1 parent 2406522 commit 4828d7a

File tree

7 files changed

+379
-590
lines changed

7 files changed

+379
-590
lines changed

src/TickerQ.EntityFrameworkCore/Infrastructure/BasePersistenceProvider.cs

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -136,25 +136,38 @@ public async Task<TimeTickerEntity[]> GetEarliestTimeTickers(CancellationToken c
136136
{
137137
await using var dbContext = await DbContextFactory.CreateDbContextAsync(cancellationToken).ConfigureAwait(false);
138138
var now = _clock.UtcNow;
139-
var mainSchedulerThreshold = now.AddMilliseconds(-now.Millisecond);
140-
139+
140+
// Define the window: ignore anything older than 1 second ago
141+
var oneSecondAgo = now.AddSeconds(-1);
142+
141143
var baseQuery = dbContext.Set<TTimeTicker>()
142144
.AsNoTracking()
143145
.Where(x => x.ExecutionTime != null)
146+
.Where(x => x.ExecutionTime >= oneSecondAgo) // Ignore old tickers (fallback handles them)
144147
.WhereCanAcquire(_lockHolder);
145-
148+
149+
// Find the earliest ticker within our window
146150
var minExecutionTime = await baseQuery
147-
.Where(x => x.ExecutionTime >= mainSchedulerThreshold)
148151
.OrderBy(x => x.ExecutionTime)
149152
.Select(x => x.ExecutionTime)
150153
.FirstOrDefaultAsync(cancellationToken).ConfigureAwait(false);
151154

152155
if (minExecutionTime == null)
153156
return [];
154-
157+
158+
// Round the minimum execution time down to its second
159+
var minSecond = new DateTime(minExecutionTime.Value.Year, minExecutionTime.Value.Month,
160+
minExecutionTime.Value.Day, minExecutionTime.Value.Hour,
161+
minExecutionTime.Value.Minute, minExecutionTime.Value.Second,
162+
DateTimeKind.Utc);
163+
164+
// Fetch all tickers within that complete second (this ensures we get all tickers in the same second)
165+
var maxExecutionTime = minSecond.AddSeconds(1);
166+
155167
return await baseQuery
156168
.Include(x => x.Children.Where(y => y.ExecutionTime == null))
157-
.Where(x => x.ExecutionTime.Value >= minExecutionTime && x.ExecutionTime <= now.AddSeconds(1).AddMilliseconds(-now.Millisecond))
169+
.Where(x => x.ExecutionTime >= minSecond && x.ExecutionTime < maxExecutionTime)
170+
.OrderBy(x => x.ExecutionTime)
158171
.Select(MappingExtensions.ForQueueTimeTickers<TTimeTicker>())
159172
.ToArrayAsync(cancellationToken).ConfigureAwait(false);
160173
}

src/TickerQ.Utilities/Managers/InternalTickerManager.cs

Lines changed: 21 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -82,36 +82,47 @@ private TimeSpan CalculateMinTimeRemaining(
8282
if (time is null)
8383
{
8484
sources = [TickerType.CronTickerOccurrence];
85-
return cron.Value - now;
85+
var cronRemaining = cron.Value - now;
86+
// Ensure we don't return negative values - schedule for immediate execution
87+
return cronRemaining < TimeSpan.Zero ? TimeSpan.Zero : cronRemaining;
8688
}
8789

8890
// only time
8991
if (cron is null)
9092
{
9193
sources = [TickerType.TimeTicker];
92-
return time.Value - now;
94+
var timeRemaining = time.Value - now;
95+
// Ensure we don't return negative values - schedule for immediate execution
96+
return timeRemaining < TimeSpan.Zero ? TimeSpan.Zero : timeRemaining;
9397
}
9498

95-
// both present - check if they're close enough to batch together
96-
var timeDiff = Math.Abs((cron.Value - time.Value).TotalMilliseconds);
99+
// both present - check if they're in the exact same second (ignoring milliseconds)
100+
var cronSecond = new DateTime(cron.Value.Year, cron.Value.Month, cron.Value.Day,
101+
cron.Value.Hour, cron.Value.Minute, cron.Value.Second);
102+
var timeSecond = new DateTime(time.Value.Year, time.Value.Month, time.Value.Day,
103+
time.Value.Hour, time.Value.Minute, time.Value.Second);
97104

98-
// Only batch if within 50ms of each other for efficiency
99-
if (timeDiff <= 250)
105+
// Only batch if they're in the exact same second
106+
if (cronSecond == timeSecond)
100107
{
101108
sources = [TickerType.CronTickerOccurrence, TickerType.TimeTicker];
102109
var earliest = cron < time ? cron.Value : time.Value;
103-
return earliest - now;
110+
var earliestRemaining = earliest - now;
111+
// Ensure we don't return negative values
112+
return earliestRemaining < TimeSpan.Zero ? TimeSpan.Zero : earliestRemaining;
104113
}
105114

106-
// Different times - only process the earliest one
115+
// Different seconds - only process the earliest one
107116
if (cron < time)
108117
{
109118
sources = [TickerType.CronTickerOccurrence];
110-
return cron.Value - now;
119+
var cronRemaining = cron.Value - now;
120+
return cronRemaining < TimeSpan.Zero ? TimeSpan.Zero : cronRemaining;
111121
}
112122

113123
sources = [TickerType.TimeTicker];
114-
return time.Value - now;
124+
var finalTimeRemaining = time.Value - now;
125+
return finalTimeRemaining < TimeSpan.Zero ? TimeSpan.Zero : finalTimeRemaining;
115126
}
116127

117128
private async Task<InternalFunctionContext[]>RetrieveEligibleTickersAsync(

src/TickerQ/Src/BackgroundServices/TickerQSchedulerBackgroundService.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using System;
2+
using System.Linq;
23
using System.Threading;
34
using System.Threading.Tasks;
45
using Microsoft.Extensions.Hosting;
@@ -104,7 +105,7 @@ private async Task RunTickerQSchedulerAsync(CancellationToken stoppingToken, Can
104105
{
105106
await _internalTickerManager.SetTickersInProgress(_executionContext.Functions, cancellationToken);
106107

107-
foreach (var function in _executionContext.Functions)
108+
foreach (var function in _executionContext.Functions.OrderBy(x => x.CachedPriority))
108109
await _taskScheduler.QueueAsync(async ct => await _taskHandler.ExecuteTaskAsync(function,false, ct), function.CachedPriority, stoppingToken);
109110
}
110111

src/TickerQ/Src/TickerQThreadPool/PriorityTask.cs

Lines changed: 0 additions & 33 deletions
This file was deleted.

src/TickerQ/Src/TickerQThreadPool/TickerQSynchronizationContext.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ public override void Post(SendOrPostCallback d, object state)
3838
else
3939
{
4040
// We're not on a TickerQ worker - safe to queue the continuation
41-
_scheduler.QueueContinuation(() => d(state));
41+
_scheduler.PostContinuation(d, state);
4242
}
4343
}
4444

0 commit comments

Comments
 (0)