-
Notifications
You must be signed in to change notification settings - Fork 20
[FEATURE] Background jobs #745
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
Changes from 11 commits
a3c57f9
ea773ec
26a411d
7219c84
ebdc245
748644e
5e3ddd4
4e52bd5
61dcd96
cf71f8f
fef565a
b1fde96
72b4fb3
9cec349
cf5ac10
be52be4
a824470
2c15147
54e5770
f4af0a2
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,13 @@ | ||
| using CrispyWaffle.BackgroundJobs.Core; | ||
Check warningCode scanning / Sonarcsharp (reported by Codacy) Add or update the header of this file. Warning
Add or update the header of this file.
Check noticeCode scanning / Sonarcsharp (reported by Codacy) Provide a 'ComVisible' attribute for assembly 'srcassembly.dll'. Note
Provide a 'ComVisible' attribute for assembly 'srcassembly.dll'.
Check noticeCode scanning / Sonarcsharp (reported by Codacy) Provide a 'CLSCompliant' attribute for assembly 'srcassembly.dll'. Note
Provide a 'CLSCompliant' attribute for assembly 'srcassembly.dll'.
Check noticeCode scanning / Sonarcsharp (reported by Codacy) Provide an 'AssemblyVersion' attribute for assembly 'srcassembly.dll'. Note
Provide an 'AssemblyVersion' attribute for assembly 'srcassembly.dll'.
|
||
|
|
||
| namespace CrispyWaffle.BackgroundJobs.Abstractions | ||
| { | ||
| /// <summary> | ||
| /// Low-level job representation (mostly used for in-memory workflows). | ||
| /// For persisted jobs, prefer IBackgroundJobHandler<TData> with registry-based activation. | ||
| /// </summary> | ||
| public interface IBackgroundJob | ||
| { | ||
| Task<JobResult> ExecuteAsync(CancellationToken cancellationToken); | ||
Check warningCode scanning / Sonarcsharp (reported by Codacy) Remove the 'Async' suffix to the name of this method. Warning
Remove the 'Async' suffix to the name of this method.
|
||
| } | ||
| } | ||
Check warningCode scanning / Sonarcsharp (reported by Codacy) Add a new line at the end of the file 'IBackgroundJob.cs'. Warning
Add a new line at the end of the file 'IBackgroundJob.cs'.
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,13 @@ | ||
| using CrispyWaffle.BackgroundJobs.Core; | ||
Check warningCode scanning / Sonarcsharp (reported by Codacy) Add or update the header of this file. Warning
Add or update the header of this file.
Check noticeCode scanning / Sonarcsharp (reported by Codacy) Provide a 'ComVisible' attribute for assembly 'srcassembly.dll'. Note
Provide a 'ComVisible' attribute for assembly 'srcassembly.dll'.
Check noticeCode scanning / Sonarcsharp (reported by Codacy) Provide a 'CLSCompliant' attribute for assembly 'srcassembly.dll'. Note
Provide a 'CLSCompliant' attribute for assembly 'srcassembly.dll'.
Check noticeCode scanning / Sonarcsharp (reported by Codacy) Provide an 'AssemblyVersion' attribute for assembly 'srcassembly.dll'. Note
Provide an 'AssemblyVersion' attribute for assembly 'srcassembly.dll'.
|
||
|
|
||
| namespace CrispyWaffle.BackgroundJobs.Abstractions | ||
| { | ||
| /// <summary> | ||
| /// Typed handler used by persisted jobs. Implement this to allow DI-resolved handlers. | ||
| /// TData is the payload type stored as JSON in the job store. | ||
| /// </summary> | ||
| public interface IBackgroundJobHandler<TData> | ||
| { | ||
| Task<JobResult> HandleAsync(TData data, CancellationToken cancellationToken); | ||
Check warningCode scanning / Sonarcsharp (reported by Codacy) Remove the 'Async' suffix to the name of this method. Warning
Remove the 'Async' suffix to the name of this method.
|
||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,9 @@ | ||
| namespace CrispyWaffle.BackgroundJobs.Abstractions | ||
Check warningCode scanning / Sonarcsharp (reported by Codacy) Add or update the header of this file. Warning
Add or update the header of this file.
Check noticeCode scanning / Sonarcsharp (reported by Codacy) Provide an 'AssemblyVersion' attribute for assembly 'srcassembly.dll'. Note
Provide an 'AssemblyVersion' attribute for assembly 'srcassembly.dll'.
Check noticeCode scanning / Sonarcsharp (reported by Codacy) Provide a 'ComVisible' attribute for assembly 'srcassembly.dll'. Note
Provide a 'ComVisible' attribute for assembly 'srcassembly.dll'.
Check noticeCode scanning / Sonarcsharp (reported by Codacy) Provide a 'CLSCompliant' attribute for assembly 'srcassembly.dll'. Note
Provide a 'CLSCompliant' attribute for assembly 'srcassembly.dll'.
|
||
| { | ||
| public interface IJobScheduler | ||
| { | ||
| Task ScheduleAsync(string handlerName, object payload, TimeSpan delay, int maxAttempts = 3, JobPriority priority = JobPriority.Normal); | ||
Check warningCode scanning / Sonarcsharp (reported by Codacy) Remove the 'Async' suffix to the name of this method. Warning
Remove the 'Async' suffix to the name of this method.
Check noticeCode scanning / Sonarcsharp (reported by Codacy) Use the overloading mechanism instead of the optional parameters. Note
Use the overloading mechanism instead of the optional parameters.
|
||
|
|
||
| Task EnqueueAsync(string handlerName, object payload, int maxAttempts = 3, JobPriority priority = JobPriority.Normal); | ||
Check warningCode scanning / Sonarcsharp (reported by Codacy) Remove the 'Async' suffix to the name of this method. Warning
Remove the 'Async' suffix to the name of this method.
Check noticeCode scanning / Sonarcsharp (reported by Codacy) Use the overloading mechanism instead of the optional parameters. Note
Use the overloading mechanism instead of the optional parameters.
|
||
| } | ||
| } | ||
Check warningCode scanning / Sonarcsharp (reported by Codacy) Add a new line at the end of the file 'IJobScheduler.cs'. Warning
Add a new line at the end of the file 'IJobScheduler.cs'.
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,19 @@ | ||
| namespace CrispyWaffle.BackgroundJobs.Abstractions | ||
Check warningCode scanning / Sonarcsharp (reported by Codacy) Add or update the header of this file. Warning
Add or update the header of this file.
Check noticeCode scanning / Sonarcsharp (reported by Codacy) Provide a 'CLSCompliant' attribute for assembly 'srcassembly.dll'. Note
Provide a 'CLSCompliant' attribute for assembly 'srcassembly.dll'.
Check noticeCode scanning / Sonarcsharp (reported by Codacy) Provide a 'ComVisible' attribute for assembly 'srcassembly.dll'. Note
Provide a 'ComVisible' attribute for assembly 'srcassembly.dll'.
Check noticeCode scanning / Sonarcsharp (reported by Codacy) Provide an 'AssemblyVersion' attribute for assembly 'srcassembly.dll'. Note
Provide an 'AssemblyVersion' attribute for assembly 'srcassembly.dll'.
|
||
| { | ||
| public interface IJobStore | ||
| { | ||
| Task SaveAsync(JobEntity job, CancellationToken cancellationToken = default); | ||
Check warningCode scanning / Sonarcsharp (reported by Codacy) Remove the 'Async' suffix to the name of this method. Warning
Remove the 'Async' suffix to the name of this method.
Check noticeCode scanning / Sonarcsharp (reported by Codacy) Use the overloading mechanism instead of the optional parameters. Note
Use the overloading mechanism instead of the optional parameters.
|
||
|
|
||
| /// <summary> | ||
| /// Fetch the next available job that is due (ScheduledAt <= UtcNow) and Pending. | ||
| /// Implementation should atomically mark it as Processing to avoid double pick-up. | ||
| /// </summary> | ||
| Task<JobEntity?> FetchNextAsync(CancellationToken cancellationToken = default); | ||
Check warningCode scanning / Sonarcsharp (reported by Codacy) Remove the 'Async' suffix to the name of this method. Warning
Remove the 'Async' suffix to the name of this method.
Check noticeCode scanning / Sonarcsharp (reported by Codacy) Use the overloading mechanism instead of the optional parameters. Note
Use the overloading mechanism instead of the optional parameters.
|
||
|
|
||
| Task MarkCompletedAsync(Guid jobId, CancellationToken cancellationToken = default); | ||
Check warningCode scanning / Sonarcsharp (reported by Codacy) Remove the 'Async' suffix to the name of this method. Warning
Remove the 'Async' suffix to the name of this method.
Check noticeCode scanning / Sonarcsharp (reported by Codacy) Use the overloading mechanism instead of the optional parameters. Note
Use the overloading mechanism instead of the optional parameters.
|
||
|
|
||
| Task MarkFailedAsync(Guid jobId, string error, CancellationToken cancellationToken = default); | ||
Check warningCode scanning / Sonarcsharp (reported by Codacy) Remove the 'Async' suffix to the name of this method. Warning
Remove the 'Async' suffix to the name of this method.
Check noticeCode scanning / Sonarcsharp (reported by Codacy) Use the overloading mechanism instead of the optional parameters. Note
Use the overloading mechanism instead of the optional parameters.
|
||
|
|
||
| Task MarkRetryAsync(Guid jobId, DateTimeOffset? nextAttemptAt, int attemptCount, CancellationToken cancellationToken = default); | ||
Check warningCode scanning / Sonarcsharp (reported by Codacy) Remove the 'Async' suffix to the name of this method. Warning
Remove the 'Async' suffix to the name of this method.
Check noticeCode scanning / Sonarcsharp (reported by Codacy) Use the overloading mechanism instead of the optional parameters. Note
Use the overloading mechanism instead of the optional parameters.
|
||
| } | ||
| } | ||
Check warningCode scanning / Sonarcsharp (reported by Codacy) Add a new line at the end of the file 'IJobStore.cs'. Warning
Add a new line at the end of the file 'IJobStore.cs'.
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,47 @@ | ||
| namespace CrispyWaffle.BackgroundJobs.Abstractions | ||
Check warningCode scanning / Sonarcsharp (reported by Codacy) Add or update the header of this file. Warning
Add or update the header of this file.
Check noticeCode scanning / Sonarcsharp (reported by Codacy) Provide an 'AssemblyVersion' attribute for assembly 'srcassembly.dll'. Note
Provide an 'AssemblyVersion' attribute for assembly 'srcassembly.dll'.
Check noticeCode scanning / Sonarcsharp (reported by Codacy) Provide a 'ComVisible' attribute for assembly 'srcassembly.dll'. Note
Provide a 'ComVisible' attribute for assembly 'srcassembly.dll'.
Check noticeCode scanning / Sonarcsharp (reported by Codacy) Provide a 'CLSCompliant' attribute for assembly 'srcassembly.dll'. Note
Provide a 'CLSCompliant' attribute for assembly 'srcassembly.dll'.
|
||
| { | ||
| using System; | ||
|
|
||
| /// <summary> | ||
| /// Persistent representation of a job. | ||
| /// HandlerName identifies a registered handler; Payload is JSON. | ||
| /// </summary> | ||
| public class JobEntity | ||
| { | ||
| public Guid Id { get; set; } = Guid.NewGuid(); | ||
|
|
||
| /// <summary> | ||
| /// Logical handler name registered in IJobHandlerRegistry. | ||
| /// </summary> | ||
| public string HandlerName { get; set; } = string.Empty; | ||
|
|
||
| /// <summary> | ||
| /// JSON payload (serialized) for the handler. | ||
| /// </summary> | ||
| public string Payload { get; set; } = string.Empty; | ||
|
|
||
| public JobPriority Priority { get; set; } = JobPriority.Normal; | ||
|
|
||
| public JobStatus Status { get; set; } = JobStatus.Pending; | ||
|
|
||
| /// <summary> | ||
| /// When the job becomes due for execution. Null means immediately. | ||
| /// </summary> | ||
| public DateTimeOffset? ScheduledAt { get; set; } | ||
|
|
||
| public int Attempt { get; set; } = 0; | ||
Check warningCode scanning / Sonarcsharp (reported by Codacy) Remove this initialization to 'Attempt', the compiler will do that for you. Warning
Remove this initialization to 'Attempt', the compiler will do that for you.
|
||
|
|
||
| public int MaxAttempt { get; set; } = 3; | ||
|
|
||
| public string? LastError { get; set; } | ||
|
|
||
| public DateTimeOffset CreatedAt { get; set; } = DateTimeOffset.UtcNow; | ||
Check noticeCode scanning / Sonarcsharp (reported by Codacy) Use a testable (date) time provider instead. Note
Use a testable (date) time provider instead.
|
||
|
|
||
| public DateTimeOffset UpdatedAt { get; set; } = DateTimeOffset.UtcNow; | ||
Check noticeCode scanning / Sonarcsharp (reported by Codacy) Use a testable (date) time provider instead. Note
Use a testable (date) time provider instead.
|
||
|
|
||
| /// <summary> | ||
| /// Optional delay in seconds between retries (used only as hint). | ||
| /// </summary> | ||
| public int RetryDelaySeconds { get; set; } = 0; | ||
Check warningCode scanning / Sonarcsharp (reported by Codacy) Remove this initialization to 'RetryDelaySeconds', the compiler will do that for you. Warning
Remove this initialization to 'RetryDelaySeconds', the compiler will do that for you.
|
||
| } | ||
| } | ||
Check warningCode scanning / Sonarcsharp (reported by Codacy) Add a new line at the end of the file 'JobEntity.cs'. Warning
Add a new line at the end of the file 'JobEntity.cs'.
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,9 @@ | ||
| namespace CrispyWaffle.BackgroundJobs.Abstractions | ||
Check warningCode scanning / Sonarcsharp (reported by Codacy) Add or update the header of this file. Warning
Add or update the header of this file.
Check noticeCode scanning / Sonarcsharp (reported by Codacy) Provide a 'ComVisible' attribute for assembly 'srcassembly.dll'. Note
Provide a 'ComVisible' attribute for assembly 'srcassembly.dll'.
Check noticeCode scanning / Sonarcsharp (reported by Codacy) Provide a 'CLSCompliant' attribute for assembly 'srcassembly.dll'. Note
Provide a 'CLSCompliant' attribute for assembly 'srcassembly.dll'.
Check noticeCode scanning / Sonarcsharp (reported by Codacy) Provide an 'AssemblyVersion' attribute for assembly 'srcassembly.dll'. Note
Provide an 'AssemblyVersion' attribute for assembly 'srcassembly.dll'.
|
||
| { | ||
| public enum JobPriority | ||
| { | ||
| High = 0, | ||
| Normal = 1, | ||
| Low = 2 | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,11 @@ | ||
| namespace CrispyWaffle.BackgroundJobs.Abstractions | ||
Check warningCode scanning / Sonarcsharp (reported by Codacy) Add or update the header of this file. Warning
Add or update the header of this file.
Check noticeCode scanning / Sonarcsharp (reported by Codacy) Provide an 'AssemblyVersion' attribute for assembly 'srcassembly.dll'. Note
Provide an 'AssemblyVersion' attribute for assembly 'srcassembly.dll'.
Check noticeCode scanning / Sonarcsharp (reported by Codacy) Provide a 'ComVisible' attribute for assembly 'srcassembly.dll'. Note
Provide a 'ComVisible' attribute for assembly 'srcassembly.dll'.
Check noticeCode scanning / Sonarcsharp (reported by Codacy) Provide a 'CLSCompliant' attribute for assembly 'srcassembly.dll'. Note
Provide a 'CLSCompliant' attribute for assembly 'srcassembly.dll'.
|
||
| { | ||
| public enum JobStatus | ||
| { | ||
| Pending = 0, | ||
| Processing = 1, | ||
| Completed = 2, | ||
| Failed = 3, | ||
| Dead = 4 | ||
| } | ||
| } | ||
Check warningCode scanning / Sonarcsharp (reported by Codacy) Add a new line at the end of the file 'JobStatus.cs'. Warning
Add a new line at the end of the file 'JobStatus.cs'.
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,47 @@ | ||
| using CrispyWaffle.BackgroundJobs.Abstractions; | ||
Check warningCode scanning / Sonarcsharp (reported by Codacy) Add or update the header of this file. Warning
Add or update the header of this file.
Check noticeCode scanning / Sonarcsharp (reported by Codacy) Provide a 'ComVisible' attribute for assembly 'srcassembly.dll'. Note
Provide a 'ComVisible' attribute for assembly 'srcassembly.dll'.
Check noticeCode scanning / Sonarcsharp (reported by Codacy) Provide a 'CLSCompliant' attribute for assembly 'srcassembly.dll'. Note
Provide a 'CLSCompliant' attribute for assembly 'srcassembly.dll'.
Check noticeCode scanning / Sonarcsharp (reported by Codacy) Provide an 'AssemblyVersion' attribute for assembly 'srcassembly.dll'. Note
Provide an 'AssemblyVersion' attribute for assembly 'srcassembly.dll'.
|
||
| using System.Threading.Channels; | ||
|
|
||
| namespace CrispyWaffle.BackgroundJobs.Core | ||
| { | ||
| /// <summary> | ||
| /// Lightweight in-memory priority queue using Channel for signaling. | ||
| /// Priorities: lower int = higher priority. | ||
| /// This queue stores JobEntity (for uniformity with persistent store model). | ||
| /// </summary> | ||
| public class BackgroundJobQueue | ||
| { | ||
| private readonly object _lock = new(); | ||
| private readonly PriorityQueue<JobEntity, int> _pq = new(); | ||
| private readonly Channel<JobEntity> _signal = Channel.CreateUnbounded<JobEntity>(new UnboundedChannelOptions { SingleReader = false, SingleWriter = false }); | ||
|
|
||
| public void Enqueue(JobEntity job) | ||
| { | ||
| lock (_lock) | ||
| { | ||
| _pq.Enqueue(job, (int)job.Priority); | ||
| } | ||
| // Always write to signal channel to notify consumers. | ||
| _ = _signal.Writer.WriteAsync(job); | ||
| } | ||
|
|
||
| public async Task<JobEntity?> DequeueAsync(CancellationToken cancellationToken) | ||
Check warningCode scanning / Sonarcsharp (reported by Codacy) Remove the 'Async' suffix to the name of this method. Warning
Remove the 'Async' suffix to the name of this method.
|
||
| { | ||
| // Wait until a job is signaled and then pop from our priority queue. | ||
| try | ||
| { | ||
| await _signal.Reader.ReadAsync(cancellationToken); | ||
| } | ||
| catch (OperationCanceledException) { return null; } | ||
|
|
||
| lock (_lock) | ||
| { | ||
| if (_pq.TryDequeue(out var job, out _)) | ||
| { | ||
| return job; | ||
| } | ||
| } | ||
|
|
||
| return null; | ||
| } | ||
| } | ||
| } | ||
Check warningCode scanning / Sonarcsharp (reported by Codacy) Add a new line at the end of the file 'BackgroundJobQueue.cs'. Warning
Add a new line at the end of the file 'BackgroundJobQueue.cs'.
|
||
Uh oh!
There was an error while loading. Please reload this page.