Skip to content

Commit 30c4eea

Browse files
skrukwaclaygeo
andcommitted
feat: add generic ProgressType parameter to Job and Worker
The progress type was hardcoded to JobProgress (string | boolean | number | object), so there was no way to get type-safe progress when calling updateProgress() or when listening to the progress event. Add an optional ProgressType generic parameter, constrained to JobProgress and defaulting to JobProgress, to MinimalJob, Job, Processor, Worker and WorkerListener. Existing code that passes fewer generics keeps compiling unchanged. Because ProgressType is constrained to JobProgress, Job<..., P> stays assignable to the internal MinimalJob helpers, which never read or write progress, so the generic does not need to be threaded through them. This also keeps the persistence contract intact, since progress is ultimately serialized before being stored in the backend. On Worker the parameter is added after the backend generic B so that the existing public signature is not broken. Sandboxed processors keep JobProgress by design, as progress crosses a process boundary where the static type is lost. Queue side getters such as getJob and Job.fromId also keep the default. Closes #3721 Co-authored-by: claygeo <claygeo6@gmail.com>
1 parent 94d3286 commit 30c4eea

6 files changed

Lines changed: 178 additions & 47 deletions

File tree

docs/gitbook/guide/workers/README.md

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,33 @@ It is also possible to specify the data types for the Job data and return value
133133
const worker = new Worker<MyData, MyReturn>(queueName, async (job: Job) => {});
134134
```
135135

136+
By default the job progress is typed as `string | boolean | number | object`. If you report progress with a specific shape, you can also specify a progress type so that `updateProgress` and the `progress` event are type-safe:
137+
138+
```typescript
139+
import { Worker, RedisQueueBackend } from 'bullmq';
140+
141+
type MyProgress = { percentage: number; message: string };
142+
143+
const worker = new Worker<
144+
MyData,
145+
MyReturn,
146+
string,
147+
RedisQueueBackend,
148+
MyProgress
149+
>(queueName, async job => {
150+
// progress is checked against MyProgress
151+
await job.updateProgress({ percentage: 42, message: 'halfway' });
152+
});
153+
154+
worker.on('progress', (job, progress) => {
155+
console.log(progress.percentage, progress.message);
156+
});
157+
```
158+
159+
{% hint style="info" %}
160+
The progress type must be JSON-serializable, as progress is persisted in the queue's backend. Sandboxed processors always receive the default progress type, since the value crosses a process boundary.
161+
{% endhint %}
162+
136163
## Read more:
137164

138165
- 💡 [Worker API Reference](https://docs.bullmq.io/api/classes/v6.Worker.html)

src/classes/job.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,8 @@ export class Job<
5555
DataType = any,
5656
ReturnType = any,
5757
NameType extends string = string,
58-
> implements MinimalJob<DataType, ReturnType, NameType> {
58+
ProgressType extends JobProgress = JobProgress,
59+
> implements MinimalJob<DataType, ReturnType, NameType, ProgressType> {
5960
/**
6061
* It includes the prefix, the namespace separator :, and queue name.
6162
* @see {@link https://www.gnu.org/software/gawk/manual/html_node/Qualified-Names.html}
@@ -66,7 +67,7 @@ export class Job<
6667
* The progress a job has performed so far.
6768
* @defaultValue 0
6869
*/
69-
progress: JobProgress = 0;
70+
progress: ProgressType = 0 as ProgressType;
7071

7172
/**
7273
* The value returned by the processor when processing this job.
@@ -539,7 +540,7 @@ export class Job<
539540
*
540541
* @param progress - number or object to be saved as progress.
541542
*/
542-
async updateProgress(progress: JobProgress): Promise<void> {
543+
async updateProgress(progress: ProgressType): Promise<void> {
543544
this.progress = progress;
544545
await this.backend.updateProgress(this.id, progress);
545546
this.queue.emit('progress', this, progress);

0 commit comments

Comments
 (0)