Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Proposal] Change IDriverDelegate to Filter Triggers for Acquisition Based on Job Type #2238

Open
da3dsoul opened this issue Jan 9, 2024 · 0 comments

Comments

@da3dsoul
Copy link

da3dsoul commented Jan 9, 2024

I am trying to build custom logic for acquiring the next jobs. I have various Job Types that do things like call external APIs, need limited (but not no) concurrency, need a database to be accessible (but not all jobs), and other conditions.
Currently, the solution is to just get more triggers, filter them, get more, filter.... It's not efficient.

My proposal is to add a filter to exclude a set of JobTypes/JobClasses to IDriverDelegate.SelectTriggerToAcquire().

Task<IReadOnlyCollection<TriggerAcquireResult>> SelectTriggerToAcquire(
            ConnectionAndTransactionHolder conn, 
            DateTimeOffset noLaterThan, 
            DateTimeOffset noEarlierThan, 
            int maxCount,
            Type[] jobTypesToExclude = null,
            CancellationToken cancellationToken = default);

It would also change StdAdoDriverDelegate.
Not the most efficient implementation, but it gets the point across.

    protected virtual string GetSelectNextTriggerToAcquireSql(int maxCount, Type[] jobTypesToExclude)
    {
        return $@"SELECT
                t.{ColumnTriggerName}, t.{ColumnTriggerGroup}, jd.{ColumnJobClass}
              FROM
                {TablePrefixSubst}{TableTriggers} t
              JOIN
                {TablePrefixSubst}{TableJobDetails} jd ON (jd.{ColumnSchedulerName} = t.{ColumnSchedulerName} AND  jd.{ColumnJobGroup} = t.{ColumnJobGroup} AND jd.{ColumnJobName} = t.{ColumnJobName}) 
              WHERE
                t.{ColumnSchedulerName} = @schedulerName AND {ColumnTriggerState} = @state AND {ColumnNextFireTime} <= @noLaterThan AND ({ColumnMifireInstruction} = -1 OR ({ColumnMifireInstruction} <> -1 AND {ColumnNextFireTime} >= @noEarlierThan))
                {(jobTypesToExclude == null || jobTypesToExclude.Length == 0 ? "" : $"AND jd.{ColumnJobClass} NOT IN ({string.Join(",", jobTypesToExclude.Select(a => $"'{GetStorableJobTypeName(a)}'"))})")} 
              ORDER BY 
                {ColumnNextFireTime} ASC, {ColumnPriority} DESC;";
    }

By filtering Job Types, it allows a developer to only make an extended JobStore with the AcquireNextTrigger method overridden in order to get triggers based on certain criteria. Due to the database design, trying to filter in SQL via any other method would likely not be maintainable or extensible.

In order to attempt a change like this without changing quartz, it would require overriding IDriverDelegate.SelectTriggerToAcquire(), adding the parameter, overriding Initialize() to get schedName (it's currently private), creating an interface and/or dirty casting in the custom JobStore... I stopped going around there and decided to see what you guys think of adding the parameter. Being able to filter the Job Type seems like it could be more efficient for many situations involving custom trigger acquisition.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant