Skip to content

Commit cbda4c1

Browse files
committed
docs: add docs on background job plugin for reactive updates
1 parent e0ccba5 commit cbda4c1

1 file changed

Lines changed: 22 additions & 15 deletions

File tree

adminforth/documentation/docs/tutorial/08-Plugins/23-background-jobs.md

Lines changed: 22 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -317,6 +317,7 @@ There may be cases when you need to display the state of job tasks. For this, yo
317317
<Button class="h-10" @click="loadTasks">
318318
Get Job Tasks
319319
</Button>
320+
{{ props.job.state.statusMessage }}
320321
{{ tasks }}
321322
</div>
322323
</template>
@@ -325,19 +326,23 @@ There may be cases when you need to display the state of job tasks. For this, yo
325326
<script setup lang="ts">
326327
import { Button, JsonViewer } from '@/afcl';
327328
import { onMounted, onUnmounted, ref } from 'vue';
328-
import websocket from '@/websocket';
329329
import type { AdminForthComponentDeclarationFull } from 'adminforth';
330330

331331

332332
const tasks = ref<{state: Record<string, any>, status: string}[]>([]);
333+
let unsubscribeJobStateFields: (() => void) | null = null;
334+
let unsubscribeTaskFields: (() => void) | null = null;
333335

334336

335337
const props = defineProps<{
336338
meta: any;
337339
getJobTasks: (limit?: number, offset?: number) => Promise<{state: Record<string, any>, status: string}[]>;
340+
subscribeToJobStateFields: (fieldNames: string[]) => () => void;
341+
subscribeToJobTaskFields: (fieldNames: string[]) => () => void;
338342
job: {
339343
id: string;
340344
name: string;
345+
state: Record<string, any>;
341346
status: 'IN_PROGRESS' | 'DONE' | 'DONE_WITH_ERRORS' | 'CANCELLED';
342347
progress: number; // 0 to 100
343348
createdAt: Date;
@@ -354,28 +359,30 @@ const loadTasks = async () => {
354359

355360
onMounted(async () => {
356361
loadTasks();
357-
websocket.subscribe(`/background-jobs-task-update/${props.job.id}`, (data: { taskIndex: number, status?: string, state?: Record<string, any> }) => {
358-
console.log('Received WebSocket message for job:', data.status);
359-
360-
if (data.state) {
361-
tasks.value[data.taskIndex].state = data.state;
362-
}
363-
if (data.status) {
364-
tasks.value[data.taskIndex].status = data.status;
365-
}
366-
367-
});
362+
unsubscribeJobStateFields = props.subscribeToJobStateFields(['statusMessage']);
363+
unsubscribeTaskFields = props.subscribeToJobTaskFields(['step', 'result']);
368364
});
369365

370366
onUnmounted(() => {
371-
console.log('Unsubscribing from WebSocket for job:', props.job.id);
372-
websocket.unsubscribe(`/background-jobs-task-update/${props.job.id}`);
367+
unsubscribeJobStateFields?.();
368+
unsubscribeTaskFields?.();
373369
});
374370

375371

376372
</script>
377373
```
378374
375+
Job state and task state can be reactive on the frontend and updated when something changes on the backend.
376+
However, to avoid unnecessary high-volume backend updates that might not be needed on the frontend,
377+
all updates are disabled out of the box, and you need to specify which fields to subscribe to.
378+
379+
Use `subscribeToJobStateFields(['fieldName'])` for specific job state fields and
380+
`subscribeToJobTaskFields(['fieldName'])` for specific task state fields. The plugin applies
381+
incoming updates to the reactive `job` prop and to the task objects returned by
382+
`getJobTasks()`. Task field subscriptions receive updates for that field from every task
383+
in the opened job. Both helpers return an unsubscribe function; the plugin also unsubscribes
384+
remaining field subscriptions when the job dialog closes.
385+
379386
380387
Now register this component explicitly:
381388
@@ -517,4 +524,4 @@ backgroundJobsPlugin.updateJobFieldsAtomically(jobId, async () => {
517524
await backgroundJobsPlugin.setJobField(jobId, 'totalUsedTokens', totalUsedTokens);
518525
})
519526

520-
```
527+
```

0 commit comments

Comments
 (0)