Jobs System
Overview
The Jobs system in NexusMods.App is how long-running background tasks are spawned.
These feature progress tracking, cancellation support, and error handling.
Examples of jobs include downloading files and installations.
Architecture
The Jobs system is built around several key components that work together to provide a comprehensive task management solution:
graph TB
subgraph "Job States"
Created[Created]
Running[Running]
Paused[Paused]
Completed[Completed]
Cancelled[Cancelled]
Failed[Failed]
end
%% Job lifecycle
Created --> Running
Running --> Paused
Paused --> Running
Running --> Completed
Running --> Cancelled
Running --> Failed
Paused --> Cancelled
graph LR
subgraph "Job Creation & Usage"
User[User Code] --> |creates| IJobDefinitionWithStart
IJobDefinitionWithStart --> |passed to via 'Begin'| JobMonitor
JobMonitor --> |creates| JobContext
JobMonitor --> |returns| JobTask
JobTask --> |returned to| User
JobTask --> |wraps| JobContext
JobContext --> |contains and cancels using| JobGroup["JobGroup<br/>(with cancellation token)"]
JobContext --> |calls StartAsync on| IJobDefinitionWithStart
end
JobGroup instances are created internally via JobGroupCreator
But that class is currently effectively unused.
Core Components
IJobDefinition
The base interface for all job definitions. Job definitions describe what work needs to be done and contain any parameters needed for execution.
public interface IJobDefinition;
public interface IJobDefinition<TResultType> : IJobDefinition
where TResultType : notnull;
IJobDefinitionWithStart
A specialized job definition that includes its own execution logic via the StartAsync
method:
public interface IJobDefinitionWithStart<in TParent, TResultType> : IJobDefinition<TResultType>
where TParent : IJobDefinition<TResultType>
where TResultType : notnull
{
ValueTask<TResultType> StartAsync(IJobContext<TParent> context);
}
IJobMonitor
The central component that manages job execution, tracking, and lifecycle:
public interface IJobMonitor
{
// Start a job with external task logic
IJobTask<TJobType, TResultType> Begin<TJobType, TResultType>(
TJobType job,
Func<IJobContext<TJobType>, ValueTask<TResultType>> task);
// Start a self-executing job
IJobTask<TJobType, TResultType> Begin<TJobType, TResultType>(TJobType job);
// Job management
void Cancel(JobId jobId);
void CancelGroup(IJobGroup group);
void CancelAll();
// Observability
ReadOnlyObservableCollection<IJob> Jobs { get; }
IObservable<IChangeSet<IJob, JobId>> GetObservableChangeSet<TJob>();
}
IJobContext
Provides the execution context for jobs, including progress reporting and cancellation support:
public interface IJobContext<out TJobDefinition> : IJobContext
where TJobDefinition: IJobDefinition
{
TJobDefinition Definition { get; }
Task YieldAsync();
CancellationToken CancellationToken { get; }
IJobMonitor Monitor { get; }
IJobGroup Group { get; }
void SetPercent<TVal>(TVal current, TVal max);
void SetRateOfProgress(double rate);
}
IJobGroup
Groups related jobs together for batch operations and shared cancellation:
public interface IJobGroup : IReadOnlyCollection<IJob>
{
CancellationToken CancellationToken { get; }
void Cancel();
bool IsCancelled { get; }
}