Update dependency Quartz.AspNetCore to 3.19.1 - #1333
#1333Open
renovate[bot] wants to merge 1 commit into
dev8BeyondDimension/Common:dev8from
renovate/quartznet-monorepoBeyondDimension/Common:renovate/quartznet-monorepoCopy head branch name to clipboard
Open
Update dependency Quartz.AspNetCore to 3.19.1#1333renovate[bot] wants to merge 1 commit intodev8BeyondDimension/Common:dev8from renovate/quartznet-monorepoBeyondDimension/Common:renovate/quartznet-monorepoCopy head branch name to clipboard
renovate[bot] wants to merge 1 commit into
dev8BeyondDimension/Common:dev8from
renovate/quartznet-monorepoBeyondDimension/Common:renovate/quartznet-monorepoCopy head branch name to clipboard
Conversation
renovate
Bot
force-pushed
the
renovate/quartznet-monorepo
branch
from
June 27, 2026 08:55
61b71ff to
58c9907
Compare
renovate
Bot
force-pushed
the
renovate/quartznet-monorepo
branch
from
July 24, 2026 19:02
58c9907 to
e8e5481
Compare
renovate
Bot
force-pushed
the
renovate/quartznet-monorepo
branch
from
July 26, 2026 16:59
e8e5481 to
351a6d7
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This PR contains the following updates:
3.14.0→3.19.1Release Notes
quartznet/quartznet (Quartz.AspNetCore)
v3.19.1Quartz.NET 3.19.1 is a small bug fix release with two targeted fixes:
DailyTimeIntervalTriggerno longer gets stuck in an infinite fire loop on DST spring-forward days, andStdSchedulerFactory.GetScheduler(schedName)now creates the scheduler when the name asked for is its own. There are no API or schema changes, so it is a drop-in upgrade from 3.19.0.Highlights
DailyTimeIntervalTriggerno longer spins on DST transition days —GetFireTimeAftercould return a time at or before the one it was given, which makesQuartzSchedulerThreadfire the trigger, compute the same next fire time, and fire again — pinning a CPU core and flooding the log. Two independent causes, both on a spring-forward day: the DST correction added for #1114 was applied to every interval size and in either direction (so every interval of an hour or less was affected, in every DST time zone), and the daily rollover toStartTimeOfDayreused whatever UTC offset the previous fire time carried (so in time zones that move the clock at midnight, such as Chile,StartTimeOfDay00:00 resolved to an instant before the transition — the same instant that was passed in). Verified across 3024 combinations of 12 time zones, both transitions, 21 intervals and 6 start times: 468 combinations produced non-advancing fire times before, none do now. (#3190, fixes #332)StdSchedulerFactory.GetScheduler(schedName)creates its own scheduler — asking a factory for the scheduler it is configured to produce returnednulluntil somebody had calledGetScheduler()first. It now creates it. Any other name stays a pure lookup, so probing for a scheduler somebody else owns still has no side effects, and the name comparison is case-insensitive to match howSchedulerRepositoryindexes names. The DI factory has behaved this way since #2845; this brings the property-configured factory in line. (#3188, reported in #2786, originally proposed in #360)What's Changed
Full Changelog: quartznet/quartznet@v3.19.0...v3.19.1
v3.19.0Quartz.NET 3.19.0 is a feature release: it adds node affinity for clustered scheduling, a fluent cron-expression builder, and richer
L/LWday-of-month expressions, plus clock-jump resilience and a modernized build and publishing pipeline. The public API is unchanged (all additions are additive), so it is a drop-in upgrade — with two things to note: the new node-affinity columns are an optional schema migration (the feature degrades gracefully without them), and a handful of previously-brokenL/LW/Wcron expressions now fire correctly (see below).Highlights
TriggerBuilder.WithPreferredNode(...); the node is preferred for acquisition but the trigger is still stolen on failover so it is never stranded if that node goes down. Adds optionalPREFERRED_NODE/PREFERRED_NODE_AUTOcolumns for ADO.NET job stores (database/schema_30_add_preferred_node.sql); when the columns are absent the scheduler logs a warning and behaves exactly as before. (#3013, #3144)CronExpressionBuilder— compose cron expressions programmatically, one field at a time, instead of hand-writing the string — handy when a schedule is assembled from user input such as a scheduling UI. (#3139)LandLWcombinable with other day-of-month values — the day-of-month field now accepts expressions such as1,15,Land the newLW-n/L-nWgrammar. This also corrects several previously-buggy edge cases:29W/31Wno longer silently skip short months,L-30Wno longer throws mid-schedule, and1,15Wnow appliesWto each day rather than only the first. These corrections change the fire times of a few expressions that were previously broken — review any storedL/LW/Wday-of-month expressions. (#2759)Note for
CronScheduleBuilderusers:AtHourAndMinuteOnGivenDaysOfWeek/WeeklyOnDayAndHourAndMinutenow emit textual day-of-week names (e.g.MON,WEDrather than2,4). The schedules are identical, but the generatedCRON_EXPRESSIONstring differs — relevant only if you compare stored cron strings byte-for-byte.What's Changed
Full Changelog: quartznet/quartznet@v3.18.2...v3.19.0
v3.18.2Quartz.NET 3.18.2 is a maintenance release that stabilizes the dashboard introduced in 3.18.0, fixes several scheduling correctness bugs, and speeds up cron next-fire-time computation. It is a drop-in upgrade from earlier 3.18.x releases — no breaking changes and no database schema migrations.
Highlights
AcquireNextTriggerand block acquisition of every other trigger. The faulting trigger is now isolated so the rest keep firing. (#3108)Quartzconfiguration section were not loaded for named schedulers. (#3113)DashboardPathwork under a fail-closedFallbackPolicy, and the Blazor circuit is allowed anonymous access under the same policy (#3098, #3120); trigger and calendar JSON deserialization is fixed (#3102); and JobDataMap and SimpleSchedule trigger details now display correctly (#3132).FORCE INDEXfix — schema-qualified table prefixes produced a malformedFORCE INDEXhint. (#3086)DateTimeOffsetchurn in the hot loop. (#3126, #3129)AddQuartzServer(#3112), and new public helpers make plugin configuration extensible (#3104).What's Changed
Full Changelog: quartznet/quartznet@v3.18.1...v3.18.2
v3.18.1Quartz.NET 3.18.1 is a maintenance release that addresses a timezone-related bug, security advisories on transitive dependencies, and an issue that prevented the new Redis distributed-lock package from publishing to nuget.org.
Highlights
GetTimeBeforefor positive-offset timezones —CronExpression.GetTimeBeforecould throwArgumentOutOfRangeExceptionfor cron expressions evaluated against timezones with positive UTC offsets (e.g.Europe/Helsinki,Asia/Tokyo). Backported frommain.Quartz.Extensions.Redis— the originalQuartz.Redispackage id from 3.18.0 collided with an unrelated v1.0.0 already on nuget.org and could not be published. The 3.18.0 release was shipped withIsPackable=falseas a workaround; 3.18.1 picks the umbrella idQuartz.Extensions.Redis(matchingQuartz.Extensions.DependencyInjection/Quartz.Extensions.Hosting) and re-enables publication. There are no consumers to migrate — the original id was never on nuget.org.What's Changed
Full Changelog: quartznet/quartznet@v3.18.0...v3.18.1
v3.18.0Quartz.NET 3.18.0 is a major feature release with 8 new capabilities, performance improvements, and important bug fixes.
New Features
RFC 5545 RRULE recurrence trigger
Quartz.NET now supports scheduling with iCalendar recurrence rules (RFC 5545 RRULE), enabling complex patterns that cannot be expressed with cron expressions — such as "2nd Monday of every month" or "last weekday of March each year."
A custom lightweight RRULE engine (~1.5K LOC) handles all frequencies (YEARLY through SECONDLY), all BY* rules (BYDAY, BYMONTHDAY, BYSETPOS, etc.), COUNT, UNTIL, INTERVAL, and WKST. No new external dependencies. No database schema changes — uses the existing SIMPROP_TRIGGERS table.
FREQ=MONTHLY;BYDAY=2MOFREQ=WEEKLY;INTERVAL=2;BYDAY=MO,WE,FRFREQ=YEARLY;BYMONTH=3;BYDAY=MO,TU,WE,TH,FR;BYSETPOS=-1FREQ=MONTHLY;BYMONTHDAY=-1FREQ=DAILY;BYDAY=MO,TU,WE,TH,FR(#2990) — Closes #1259
Execution groups for per-node thread limits
Tag triggers with an execution group to limit how many threads a category of jobs can consume concurrently on each node. This prevents resource-intensive jobs from starving lightweight work.
Also configurable via properties (
quartz.executionLimit.batch-jobs = 2) and runtime API (scheduler.SetExecutionLimits(...)). Includes optionalEXECUTION_GROUPcolumn for ADO.NET job stores with graceful fallback when absent, and Dashboard integration.(#3004) — Closes #1175, #830
Multiple named schedulers in Microsoft DI
Register multiple independent scheduler instances in a single DI container. Each named scheduler gets isolated options, jobs, triggers, listeners, and calendars.
AddQuartzHostedService()automatically manages the lifecycle of all registered schedulers.(#3000) — Closes #2109
JSON configuration and scheduling data
Configure Quartz.NET using hierarchical JSON in
appsettings.jsoninstead of flat property keys. Supports declarative job and trigger definitions, all 4 trigger types, and named schedulers via aSchedulerssection.{ "Quartz": { "Scheduler": { "InstanceName": "My Scheduler" }, "ThreadPool": { "MaxConcurrency": 10 }, "Schedule": { "Jobs": [{ "Name": "myJob", "JobType": "MyApp.Jobs.MyJob, MyApp", "Durable": true }], "Triggers": [{ "Name": "myTrigger", "JobName": "myJob", "Cron": { "Expression": "0/30 * * * * ?" } }] } } }Also includes a standalone
JsonSchedulingDataProcessorPluginforquartz_jobs.jsonfile support with hot-reload, mirroringXMLSchedulingDataProcessorPlugin.(#3012, #3015, #3017) — Closes #1755
Redis-based distributed lock handler (new
Quartz.Redispackage)New
Quartz.RedisNuGet package providingRedisSemaphore— anISemaphoreimplementation using RedisSET NX PXdistributed locks instead of database row locks. This eliminates DB row lock contention and deadlocks in clustered setups while keeping job/trigger data in the relational database.Uses two-tier locking: local
SemaphoreSlimprevents redundant Redis round-trips within the same process, and a Lua script ensures atomic check-and-delete on release for safety.(#2999) — Closes #1625
Activity tracing for ADO.NET job store operations
28
IJobStoremethods are now wrapped withSystem.Diagnostics.Activityspans, so database calls appear as children of named Quartz operations (e.g.,Quartz.JobStore.AcquireNextTriggers) instead of orphaned root spans in your tracing system. Zero overhead when tracing is disabled.All new operations are automatically included in
QuartzInstrumentationOptions.DefaultTracedOperations.(#3001) — Closes #2721
UpdateTriggerDetails — update trigger metadata without rescheduling
New
UpdateTriggerDetailsmethod updates Description, Priority, JobDataMap, CalendarName, and MisfireInstruction on an existing trigger without resetting fire times, trigger state, or misfire context. Available viaIScheduler.UpdateTriggerDetails()extension method.(#2988) — Closes #844
Factory-based
AddQuartz()withIServiceProvideraccessNew
AddQuartzoverloads acceptingAction<IServiceCollectionQuartzConfigurator, IServiceProvider>allow resolving DI services during Quartz configuration — useful for obtaining connection strings, feature flags, or other configuration from DI-registered services.(#3007) — Closes #1617
Performance
Reduced DB round-trips in misfire recovery
Misfire recovery now uses a targeted
UPDATEinstead of routing each trigger through the fullStoreTriggerpath, reducing per-trigger DB round-trips from 7-12 down to 1-2 (~87% reduction). For a batch of 20 cron triggers, this drops from ~150 queries to ~20 queries — all underLockTriggerAccess. Calendar lookups are also cached across the batch.(#2993) — Closes #758
Bug Fixes
SemaphoreSlim(0, 1)inQuartzSchedulerThreadcould silently drop scheduling signals viaSemaphoreFullException, causing triggers to stay stuck in WAITING state until the next idle loop timeout. (#3033) — Fixes #3028SchedulerRepositoryindexed by scheduler name only, preventing multiple remote proxies to different nodes in the same cluster from coexisting. Now supports instance-aware lookup. (#2991) — Fixes #388IsJobGroupPaused/IsTriggerGroupPausedin ADO.NET job store — These methods previously threwNotImplementedExceptionin the persistent job store. (#3030)ServiceProvider— Dashboard plugins no longer rely on a staticServiceProviderreference, fixing issues with multiple host instances. (#3035) — Fixes #3026Deprecations
DirtyFlagMap.Get()— use the indexer (map[key]) instead (#2986)DirtyFlagMap.Put()/PutAll()— use the indexer or collection initializer instead (#2989)What's Changed
Full Changelog: quartznet/quartznet@v3.17.1...v3.18.0
v3.17.1Highlights
Jenkins-style H (hash) token for cron expressions
Quartz.NET now supports the
H(hash) token in cron expressions, inspired by Jenkins. TheHtoken resolves to a deterministic value based on the trigger's identity, spreading job execution times to avoid the thundering herd problem when many triggers share the same schedule.Supported forms:
H,H(min-max),H/step,H(min-max)/stepThe hash seed is automatically derived from the trigger's identity (name + group) when using
TriggerBuilder, or can be provided explicitly. See the cron trigger documentation for full details.Structured logging history plugins
New
StructuredLoggingJobHistoryPluginandStructuredLoggingTriggerHistoryPluginprovide first-class support for structured logging frameworks like Serilog and NLog. Unlike the existing logging plugins that use index-based format placeholders ({0},{1}), these use named MEL-style message template parameters ({JobName},{TriggerGroup}, etc.), making log output queryable in structured logging sinks and avoiding template cache memory leaks.Message templates are fully configurable via standard Quartz property configuration.
Bug Fixes
updateTriggers: trueno longer resets paused triggers back to normal state. (#2968)/_blazorendpoint conflict — The Quartz Dashboard no longer conflicts with host applications that also use Blazor. (#2975)Full Changelog: quartznet/quartznet@v3.17.0...v3.17.1
v3.17.0This is a major bug-fix release with 40+ fixes spanning trigger state management, clustering reliability, DST handling, misfire accuracy, and scheduler lifecycle. An optional database schema migration improves misfire handling.
Highlights
Optional database migration:
MISFIRE_ORIG_FIRE_TIMEcolumnA new optional column
MISFIRE_ORIG_FIRE_TIMEonQRTZ_TRIGGERSenables correctScheduledFireTimeUtcfor misfired triggers when using "fire now" misfire policies. Without it,ScheduledFireTimeUtcequalsFireTimeUtcfor misfired triggers (the pre-existing behavior). RAMJobStore does not require this migration.Migration script:
database/schema_30_add_misfire_orig_fire_time.sql(covers SQL Server, PostgreSQL, MySQL, SQLite, Oracle, Firebird)Clustering and concurrency fixes
DisallowConcurrentExecutionjobs running simultaneously in cluster (#2697)DisallowConcurrentExecutionviolation (#2915)DisallowConcurrentExecutionjobs (#2822)FIRED_TRIGGERSnot cleaned up on job deletion mid-execution (#1696)Trigger state and fire time accuracy
GetTriggerStatereturning Complete instead of Blocked for executing triggers (#2255)RAMJobStore.TriggersFiredskipping triggers causing wrong trigger/job execution (#1386)ScheduledFireTimeUtcreturning wrong value after misfire (#2899)PreviousFireTimeUtcreset to null on restart withOverWriteExistingData=true(#1834)SimpleTriggerfirst fire time wrong when created long before scheduling (#2455)CronTriggerdouble-firing when rescheduled with oldStartTimeUtc(#2909)JobData(#2083)DoNothingmisfire policy skipping fire times within threshold (#2912)DST and time handling
DailyTimeIntervalTriggerextra fire during DST fall-back (#2917)DailyTimeIntervalTriggermutatingStartTimeUtcduring fire time computation (#2906)DailyTimeIntervalTriggerRepeatCountto apply per day (#1633)ComputeFireTimesBetweenmodifying trigger StartTimeUtc (#2722)Scheduler lifecycle and threading
Monitor.Waitwith asyncSemaphoreSlim(#2877)DedicatedThreadPoolthreads leaking on scheduler shutdown (#1357)Job execution
RefireImmediatelywithJobChainingJobListenerfiring chain prematurely (#663)AsyncLocalflow fromIJobFactory.NewJobtoIJob.Execute(#1528)IJobDetailproperty toJobExecutionException(#1442)API and configuration
idleWaitTimeof zero silently ignored instead of throwing (#1394)AddJob/AddTriggerambiguous references without removing overloads (#2795)PauseJobs/ResumeJobinteraction bug in RAMJobStore (#761)RemoteSchedulerignoring localquartz.scheduler.instanceName(#313)Dashboard
What's Changed
Full Changelog: quartznet/quartznet@v3.16.1...v3.17.0
v3.16.1: Quartz.NET 3.16.1This release hopefully fixes the hiccup we had with the versioning/packaging of the new Dashboard package.
What's Changed
Full Changelog: quartznet/quartznet@v3.16.0...v3.16.1
v3.16.0: Quartz.NET 3.16.0On top of great community fixes, this release also brings the experimental Dashboard into action. You can enable it on NET 8 and later, see documentation for details.
What's Changed
CalendarIntervalTriggerImplby @jafin in #2837Configuration
📅 Schedule: (in timezone Asia/Shanghai)
🚦 Automerge: Enabled.
♻ Rebasing: Whenever PR is behind base branch, or you tick the rebase/retry checkbox.
🔕 Ignore: Close this PR and you won't be reminded about this update again.
This PR was generated by Mend Renovate. View the repository job log.