@meith/tasks 0.33.3 → 0.34.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +2 -2
- package/src/builtin.ts +37 -1
- package/src/health.ts +10 -1
- package/src/index.ts +7 -1
- package/src/types.ts +1 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@meith/tasks",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.34.0",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
"main": "./src/index.ts",
|
|
12
12
|
"types": "./src/index.ts",
|
|
13
13
|
"dependencies": {
|
|
14
|
-
"@meith/core": "^0.
|
|
14
|
+
"@meith/core": "^0.34.0"
|
|
15
15
|
},
|
|
16
16
|
"files": [
|
|
17
17
|
"src",
|
package/src/builtin.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { TaskDefinition } from './types'
|
|
1
|
+
import type { TaskContext, TaskDefinition } from './types'
|
|
2
2
|
|
|
3
3
|
export interface TaskWorkers {
|
|
4
4
|
relayOutbox(batchSize: number): Promise<number>
|
|
@@ -28,8 +28,21 @@ export interface TaskWorkers {
|
|
|
28
28
|
sweepAttachments(batchSize: number): Promise<{ deleted: number; failed: number }>
|
|
29
29
|
sweepAvatars(batchSize: number): Promise<number>
|
|
30
30
|
rollUpStatistics(): Promise<{ memberCount: number; online: number; record: boolean }>
|
|
31
|
+
runBackups(context: TaskContext): Promise<BackupTaskOutcome>
|
|
31
32
|
}
|
|
32
33
|
|
|
34
|
+
export interface BackupTaskOutcome {
|
|
35
|
+
readonly ran: number
|
|
36
|
+
readonly trigger?: string
|
|
37
|
+
readonly bundle?: string
|
|
38
|
+
readonly status?: string
|
|
39
|
+
readonly skipped?: string
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export const BACKUP_TASK_ID = 'backup.run'
|
|
43
|
+
|
|
44
|
+
export const BACKUP_TASK_MAX_SECONDS = 6 * 60 * 60
|
|
45
|
+
|
|
33
46
|
function allDefinitions(workers: TaskWorkers): TaskDefinition[] {
|
|
34
47
|
return [
|
|
35
48
|
{
|
|
@@ -424,6 +437,28 @@ function allDefinitions(workers: TaskWorkers): TaskDefinition[] {
|
|
|
424
437
|
},
|
|
425
438
|
},
|
|
426
439
|
|
|
440
|
+
{
|
|
441
|
+
id: BACKUP_TASK_ID,
|
|
442
|
+
title: 'Take due backups',
|
|
443
|
+
titleKey: 'adminSystem.task.backupRun.title',
|
|
444
|
+
description:
|
|
445
|
+
'Runs the backup an administrator asked for, or the one the schedule says ' +
|
|
446
|
+
'is due, one at a time: the database dump, the uploads when the settings ' +
|
|
447
|
+
'include them, a bundle in the backup directory, a copy at the off-site ' +
|
|
448
|
+
'destination, and the pruning of whatever the retention rules no longer ' +
|
|
449
|
+
'keep. Checks every minute and does nothing most of the time. The worker ' +
|
|
450
|
+
'runs it in a lane of its own, because a dump of a large board takes ' +
|
|
451
|
+
'minutes and the outbox should not wait for it.',
|
|
452
|
+
descriptionKey: 'adminSystem.task.backupRun.description',
|
|
453
|
+
intervalSeconds: 60,
|
|
454
|
+
maxDurationSeconds: BACKUP_TASK_MAX_SECONDS,
|
|
455
|
+
lane: 'long',
|
|
456
|
+
async run(context) {
|
|
457
|
+
const outcome = await workers.runBackups(context)
|
|
458
|
+
return { detail: { ...outcome } }
|
|
459
|
+
},
|
|
460
|
+
},
|
|
461
|
+
|
|
427
462
|
{
|
|
428
463
|
id: 'stats.rollup',
|
|
429
464
|
title: 'Roll up board statistics',
|
|
@@ -471,6 +506,7 @@ const REQUIRED_WORKER: Readonly<Record<string, keyof TaskWorkers>> = {
|
|
|
471
506
|
'attachments.sweep': 'sweepAttachments',
|
|
472
507
|
'avatars.sweep': 'sweepAvatars',
|
|
473
508
|
'stats.rollup': 'rollUpStatistics',
|
|
509
|
+
[BACKUP_TASK_ID]: 'runBackups',
|
|
474
510
|
}
|
|
475
511
|
|
|
476
512
|
export function builtinTasks(workers: Partial<TaskWorkers>): TaskDefinition[] {
|
package/src/health.ts
CHANGED
|
@@ -4,10 +4,18 @@ export interface TaskHealthInput {
|
|
|
4
4
|
readonly enabled: boolean
|
|
5
5
|
readonly lastRunAt: Date | null
|
|
6
6
|
readonly nextRunAt: Date | null
|
|
7
|
+
readonly lockedUntil?: Date | null | undefined
|
|
7
8
|
readonly consecutiveFailures: number
|
|
8
9
|
}
|
|
9
10
|
|
|
10
|
-
export type TaskHealthStatus =
|
|
11
|
+
export type TaskHealthStatus =
|
|
12
|
+
| 'healthy'
|
|
13
|
+
| 'running'
|
|
14
|
+
| 'late'
|
|
15
|
+
| 'stale'
|
|
16
|
+
| 'failing'
|
|
17
|
+
| 'disabled'
|
|
18
|
+
| 'never-run'
|
|
11
19
|
|
|
12
20
|
export interface TaskHealth extends TaskHealthInput {
|
|
13
21
|
readonly status: TaskHealthStatus
|
|
@@ -31,6 +39,7 @@ export function assessTask(task: TaskHealthInput, now: Date): TaskHealth {
|
|
|
31
39
|
const status = ((): TaskHealthStatus => {
|
|
32
40
|
if (!task.enabled) return 'disabled'
|
|
33
41
|
if (task.consecutiveFailures >= FAILING_THRESHOLD) return 'failing'
|
|
42
|
+
if (task.lockedUntil != null && task.lockedUntil.getTime() > now.getTime()) return 'running'
|
|
34
43
|
if (task.lastRunAt === null) return 'never-run'
|
|
35
44
|
if (intervalsLate >= STALE_INTERVALS) return 'stale'
|
|
36
45
|
if (intervalsLate >= 1) return 'late'
|
package/src/index.ts
CHANGED
package/src/types.ts
CHANGED