Jobs
Jobs represent long-running operations the Chronicle Kernel performs in the background — replaying a projection, rebuilding a read model, and similar work that runs in steps over time rather than completing instantly. Use the jobs API to see what’s running, check progress, and stop, resume, or delete a job.
List all jobs
Section titled “List all jobs”using Cratis.Chronicle;using Cratis.Chronicle.Jobs;
public class JobsIndexListAll(IEventStore eventStore){ public async Task<IEnumerable<Job>> GetAllJobs() => await eventStore.Jobs.GetJobs();}import io.cratis.chronicle.EventStore
suspend fun listJobs(store: EventStore) { store.jobs.getJobs().forEach { job -> println("${job.type}: ${job.status}") }}import Cratis.Chronicle.Contracts.Jobs.JobsOuterClass;
import io.cratis.chronicle.EventStore;
import io.cratis.chronicle.java.JobsServiceJavaBridge;
import java.util.List;
class JobsIndexListAll { void listJobs(EventStore store) { List<JobsOuterClass.Job> jobs = JobsServiceJavaBridge.getJobs(store.getJobs()); for (JobsOuterClass.Job job : jobs) { System.out.println(job.getType() + ": " + job.getStatus()); } }}defmodule MyApp.JobsIndexListAll do def get_all_jobs do Chronicle.Jobs.all() endendimport { IEventStore } from '@cratis/chronicle';import { Job } from '@cratis/chronicle.contracts';
class JobsIndexListAll { constructor(private readonly store: IEventStore) {}
async getAllJobs(): Promise<Job[]> { return this.store.jobs.getJobs(); }}Get a single job
Section titled “Get a single job”using Cratis.Chronicle;using Cratis.Chronicle.Jobs;
public class JobsIndexGetOne(IEventStore eventStore){ public async Task<Job?> GetJob(JobId jobId) => await eventStore.Jobs.GetJob(jobId);}import io.cratis.chronicle.EventStore
suspend fun getReindexJob(store: EventStore, jobId: String) { val job = store.jobs.getJob(jobId) if (job != null) { println("${job.type}: ${job.status}") }}import Cratis.Chronicle.Contracts.Jobs.JobsOuterClass;
import io.cratis.chronicle.EventStore;
import io.cratis.chronicle.java.JobsServiceJavaBridge;
class JobsIndexGetOne { void getReindexJob(EventStore store, String jobId) { JobsOuterClass.Job job = JobsServiceJavaBridge.getJob(store.getJobs(), jobId); if (job != null) { System.out.println(job.getType() + ": " + job.getStatus()); } }}defmodule MyApp.JobsIndexGetOne do def get_job(job_id) do Chronicle.Jobs.get(job_id) endendimport { IEventStore } from '@cratis/chronicle';import { Job } from '@cratis/chronicle.contracts';
class JobsIndexGetOne { constructor(private readonly store: IEventStore) {}
async getJob(jobId: string): Promise<Job | undefined> { return this.store.jobs.getJob(jobId); }}A missing job resolves to nothing rather than an error — check for that before using the result.
Get the steps for a job
Section titled “Get the steps for a job”A job is made up of one or more steps. Get them to see fine-grained progress:
using Cratis.Chronicle;using Cratis.Chronicle.Jobs;
public class JobsIndexGetSteps(IEventStore eventStore){ public async Task<IEnumerable<JobStep>?> GetSteps(JobId jobId) { var job = await eventStore.Jobs.GetJob(jobId); return job is null ? null : await job.GetJobSteps(); }}import io.cratis.chronicle.EventStore
suspend fun listJobSteps(store: EventStore, jobId: String) { store.jobs.getJobSteps(jobId).forEach { step -> println("${step.name}: ${step.status}") }}import Cratis.Chronicle.Contracts.Jobs.JobsOuterClass;
import io.cratis.chronicle.EventStore;
import io.cratis.chronicle.java.JobsServiceJavaBridge;
import java.util.List;
class JobsIndexGetSteps { void listJobSteps(EventStore store, String jobId) { List<JobsOuterClass.JobStep> steps = JobsServiceJavaBridge.getJobSteps(store.getJobs(), jobId); for (JobsOuterClass.JobStep step : steps) { System.out.println(step.getName() + ": " + step.getStatus()); } }}defmodule MyApp.JobsIndexGetSteps do def get_steps(job_id) do Chronicle.Jobs.steps(job_id) endendimport { IEventStore } from '@cratis/chronicle';import { JobStep } from '@cratis/chronicle.contracts';
class JobsIndexGetSteps { constructor(private readonly store: IEventStore) {}
async getSteps(jobId: string): Promise<JobStep[]> { return this.store.jobs.getJobSteps(jobId); }}Stop, resume, and delete
Section titled “Stop, resume, and delete”using Cratis.Chronicle;using Cratis.Chronicle.Jobs;
public class JobsIndexStopResumeDelete(IEventStore eventStore){ public async Task StopJob(JobId jobId) => await eventStore.Jobs.Stop(jobId);
public async Task ResumeJob(JobId jobId) => await eventStore.Jobs.Resume(jobId);
public async Task DeleteJob(JobId jobId) => await eventStore.Jobs.Delete(jobId);}import io.cratis.chronicle.EventStore
suspend fun controlJob(store: EventStore, jobId: String) { store.jobs.stop(jobId) store.jobs.resume(jobId) store.jobs.delete(jobId)}import io.cratis.chronicle.EventStore;
import io.cratis.chronicle.java.JobsServiceJavaBridge;
class JobsIndexControl { void controlJob(EventStore store, String jobId) { JobsServiceJavaBridge.stop(store.getJobs(), jobId); JobsServiceJavaBridge.resume(store.getJobs(), jobId); JobsServiceJavaBridge.delete(store.getJobs(), jobId); }}defmodule MyApp.JobsIndexStopResumeDelete do def stop_job(job_id), do: Chronicle.Jobs.stop(job_id) def resume_job(job_id), do: Chronicle.Jobs.resume(job_id) def delete_job(job_id), do: Chronicle.Jobs.delete(job_id)endimport { IEventStore } from '@cratis/chronicle';
class JobsIndexStopResumeDelete { constructor(private readonly store: IEventStore) {}
async stopJob(jobId: string): Promise<void> { await this.store.jobs.stop(jobId); }
async resumeJob(jobId: string): Promise<void> { await this.store.jobs.resume(jobId); }
async deleteJob(jobId: string): Promise<void> { await this.store.jobs.delete(jobId); }}Related topics
Section titled “Related topics”- Webhooks — pushing observed events to external HTTP endpoints, the other kernel-managed background concern.