@balena/pinejs 16.2.0-build-joshbwlng-tasks-56c035f7e142216b5cf56fc7d861ce4b51157a41-1 → 16.2.0-build-joshbwlng-tasks-009b08b1f157611c22f2425c25f905d5a59aaabe-1

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.
@@ -1,6 +1,14 @@
1
1
  - commits:
2
+ - subject: Cleanup
3
+ hash: 009b08b1f157611c22f2425c25f905d5a59aaabe
4
+ body: ""
5
+ footer:
6
+ Change-type: patch
7
+ change-type: patch
8
+ author: Josh Bowling
9
+ nested: []
2
10
  - subject: Add async tasks
3
- hash: 56c035f7e142216b5cf56fc7d861ce4b51157a41
11
+ hash: 1297814070f10e99d7bd475c28c365cc03081096
4
12
  body: ""
5
13
  footer:
6
14
  Change-type: minor
@@ -9,7 +17,7 @@
9
17
  nested: []
10
18
  version: 16.2.0
11
19
  title: ""
12
- date: 2024-04-25T23:07:33.307Z
20
+ date: 2024-04-30T05:37:15.944Z
13
21
  - commits:
14
22
  - subject: Update @balena/odata-to-abstract-sql to 6.2.7
15
23
  hash: 76b2f842af0b49ef2956db23a22758fc0d1e50a0
package/CHANGELOG.md CHANGED
@@ -5,8 +5,9 @@ automatically by Versionist. DO NOT EDIT THIS FILE MANUALLY!
5
5
  This project adheres to [Semantic Versioning](http://semver.org/).
6
6
 
7
7
  # v16.2.0
8
- ## (2024-04-25)
8
+ ## (2024-04-30)
9
9
 
10
+ * Cleanup [Josh Bowling]
10
11
  * Add async tasks [Josh Bowling]
11
12
 
12
13
  # v16.1.3
@@ -1,6 +1,6 @@
1
1
  import type { Schema } from 'ajv';
2
2
  import type * as Db from '../database-layer/db';
3
- import type { sbvrUtils } from '../server-glue/module';
3
+ import * as sbvrUtils from '../sbvr-api/sbvr-utils';
4
4
  import type { TaskHandler } from './types';
5
5
  export * from './types';
6
6
  export declare const config: {
@@ -32,6 +32,7 @@ const env_1 = require("../config-loader/env");
32
32
  const errors_1 = require("../sbvr-api/errors");
33
33
  const hooks_1 = require("../sbvr-api/hooks");
34
34
  const sbvr_utils_1 = require("../sbvr-api/sbvr-utils");
35
+ const sbvrUtils = __importStar(require("../sbvr-api/sbvr-utils"));
35
36
  const common_1 = require("./common");
36
37
  const worker_1 = require("./worker");
37
38
  __exportStar(require("./types"), exports);
@@ -48,20 +49,54 @@ exports.config = {
48
49
  };
49
50
  async function createTrigger(tx) {
50
51
  await tx.executeSql(`
51
- CREATE OR REPLACE FUNCTION notify_task_insert()
52
- RETURNS TRIGGER AS $$
53
- BEGIN
54
- PERFORM pg_notify('${common_1.channel}', NEW.id::text);
55
- RETURN NEW;
56
- END;
57
- $$ LANGUAGE plpgsql;
58
- `);
52
+ CREATE OR REPLACE FUNCTION notify_task_insert()
53
+ RETURNS TRIGGER AS $$
54
+ BEGIN
55
+ PERFORM pg_notify('${common_1.channel}', NEW.id::text);
56
+ RETURN NEW;
57
+ END;
58
+ $$ LANGUAGE plpgsql;
59
+ `);
59
60
  await tx.executeSql(`
60
- CREATE OR REPLACE TRIGGER task_insert_trigger
61
- AFTER INSERT ON task
62
- FOR EACH ROW WHEN (NEW.status = 'pending' AND NEW."is scheduled to execute on-time" IS NULL)
63
- EXECUTE FUNCTION notify_task_insert();
64
- `);
61
+ CREATE OR REPLACE TRIGGER task_insert_trigger
62
+ AFTER INSERT ON task
63
+ FOR EACH ROW WHEN (NEW.status = 'queued' AND NEW."is scheduled to execute on-time" IS NULL)
64
+ EXECUTE FUNCTION notify_task_insert();
65
+ `);
66
+ }
67
+ async function createIndexes(tx) {
68
+ await tx.executeSql(`
69
+ CREATE INDEX IF NOT EXISTS idx_task_poll ON task USING btree (
70
+ "is executed by-handler",
71
+ "is scheduled to execute on-time" ASC,
72
+ "priority" DESC,
73
+ "id" ASC
74
+ ) WHERE status = 'queued';
75
+ `);
76
+ await tx.executeSql(`
77
+ CREATE INDEX IF NOT EXISTS idx_task_queued ON task (
78
+ "id",
79
+ "is created by-actor"
80
+ ) WHERE status = 'queued';
81
+ `);
82
+ }
83
+ async function adjustPriority(actor, priority) {
84
+ const result = await sbvrUtils.db.executeSql(`SELECT "is created by-actor", COUNT("id") AS task_count
85
+ FROM (
86
+ SELECT "id", "is created by-actor"
87
+ FROM task
88
+ WHERE "status" = 'queued'
89
+ ORDER BY "id" DESC
90
+ LIMIT 100
91
+ ) AS recent_tasks
92
+ GROUP BY "is created by-actor"
93
+ ORDER BY task_count DESC;
94
+ `);
95
+ if (result.rows.some((row) => parseInt(row.task_count, 10) >= 49 &&
96
+ row['is created by-actor'] !== actor)) {
97
+ return priority + 1;
98
+ }
99
+ return priority;
65
100
  }
66
101
  let worker = null;
67
102
  async function setup(db, tx) {
@@ -69,6 +104,7 @@ async function setup(db, tx) {
69
104
  return;
70
105
  }
71
106
  await createTrigger(tx);
107
+ await createIndexes(tx);
72
108
  const client = new sbvr_utils_1.PinejsClient({
73
109
  apiPrefix: `/${common_1.apiRoot}/`,
74
110
  });
@@ -80,10 +116,11 @@ async function setup(db, tx) {
80
116
  if (request.values.is_created_by__actor == null) {
81
117
  throw new errors_1.BadRequestError('Creating tasks with missing actor on req is not allowed');
82
118
  }
83
- request.values.status = 'pending';
119
+ request.values.status = 'queued';
84
120
  request.values.attempt_count = 0;
85
121
  request.values.priority ??= 1;
86
122
  request.values.attempt_limit ??= 1;
123
+ request.values.priority = await adjustPriority(request.values.is_created_by__actor, request.values.priority);
87
124
  if (request.values.is_scheduled_with__cron_expression != null &&
88
125
  request.values.is_scheduled_to_execute_on__time == null) {
89
126
  try {
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/tasks/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/tasks/index.ts"],"names":[],"mappings":"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"}
@@ -45,7 +45,7 @@ Fact type: task is scheduled to execute on time
45
45
  Necessity: each task is scheduled to execute on at most one time
46
46
  Fact type: task has status
47
47
  Necessity: each task has exactly one status
48
- Definition: "pending" or "cancelled" or "success" or "failed"
48
+ Definition: "queued" or "cancelled" or "succeeded" or "failed"
49
49
  Fact type: task started on time
50
50
  Necessity: each task started on at most one time
51
51
  Fact type: task ended on time
@@ -2,7 +2,7 @@ import type { ValidateFunction } from 'ajv';
2
2
  import type { AnyObject } from 'pinejs-client-core';
3
3
  import type * as Db from '../database-layer/db';
4
4
  import type { PinejsClient } from '../sbvr-api/sbvr-utils';
5
- export declare const taskStatuses: readonly ["pending", "cancelled", "success", "failed"];
5
+ export declare const taskStatuses: readonly ["queued", "cancelled", "succeeded", "failed"];
6
6
  export type TaskStatus = (typeof taskStatuses)[number];
7
7
  export interface Task {
8
8
  id: number;
@@ -2,9 +2,9 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.taskStatuses = void 0;
4
4
  exports.taskStatuses = [
5
- 'pending',
5
+ 'queued',
6
6
  'cancelled',
7
- 'success',
7
+ 'succeeded',
8
8
  'failed',
9
9
  ];
10
10
  //# sourceMappingURL=types.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/tasks/types.ts"],"names":[],"mappings":";;;AAKa,QAAA,YAAY,GAAG;IAC3B,SAAS;IACT,WAAW;IACX,SAAS;IACT,QAAQ;CACC,CAAC"}
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/tasks/types.ts"],"names":[],"mappings":";;;AAKa,QAAA,YAAY,GAAG;IAC3B,QAAQ;IACR,WAAW;IACX,WAAW;IACX,QAAQ;CACC,CAAC"}
@@ -25,6 +25,7 @@ var __importStar = (this && this.__importStar) || function (mod) {
25
25
  Object.defineProperty(exports, "__esModule", { value: true });
26
26
  exports.Worker = void 0;
27
27
  const env_1 = require("../config-loader/env");
28
+ const db_1 = require("../database-layer/db");
28
29
  const permissions = __importStar(require("../sbvr-api/permissions"));
29
30
  const sbvr_utils_1 = require("../sbvr-api/sbvr-utils");
30
31
  const module_1 = require("../server-glue/module");
@@ -66,23 +67,34 @@ class Worker {
66
67
  await this.finalize(tx, task, startedOnTime, 'failed', `Invalid parameter set: ${common_1.ajv.errorsText(handler.validate.errors)}`);
67
68
  return;
68
69
  }
69
- await tx.executeSql(`SAVEPOINT task_${task.id}`);
70
- const result = await handler.fn({
71
- api: new sbvr_utils_1.PinejsClient({
72
- passthrough: {
73
- tx,
74
- },
75
- }),
76
- params: task.is_executed_with__parameter_set ?? {},
77
- tx,
78
- });
79
- if (result.status === 'success') {
80
- await tx.executeSql(`RELEASE SAVEPOINT task_${task.id}`);
70
+ let status = 'queued';
71
+ let error;
72
+ try {
73
+ await module_1.sbvrUtils.db.transaction(async (handlerTx) => {
74
+ const results = await handler.fn({
75
+ api: new sbvr_utils_1.PinejsClient({
76
+ passthrough: {
77
+ tx: handlerTx,
78
+ },
79
+ }),
80
+ params: task.is_executed_with__parameter_set ?? {},
81
+ tx: handlerTx,
82
+ });
83
+ status = results.status;
84
+ error = results.error;
85
+ if (results.status !== 'succeeded' && !handlerTx.isClosed()) {
86
+ await handlerTx.rollback();
87
+ }
88
+ });
89
+ }
90
+ catch (err) {
91
+ if (!(err instanceof db_1.TransactionClosedError)) {
92
+ throw err;
93
+ }
81
94
  }
82
- else {
83
- await tx.executeSql(`ROLLBACK TO SAVEPOINT task_${task.id}`);
95
+ finally {
96
+ await this.finalize(tx, task, startedOnTime, status, error);
84
97
  }
85
- await this.finalize(tx, task, startedOnTime, result.status, result.error);
86
98
  }
87
99
  catch (err) {
88
100
  console.error('Task execution failed:', err);
@@ -102,7 +114,7 @@ class Worker {
102
114
  ...(errorMessage != null && { error_message: errorMessage }),
103
115
  };
104
116
  if (status === 'failed' && attemptCount < task.attempt_limit) {
105
- body.status = 'pending';
117
+ body.status = 'queued';
106
118
  body.is_scheduled_to_execute_on__time =
107
119
  this.getNextAttemptTime(attemptCount);
108
120
  }
@@ -115,7 +127,7 @@ class Worker {
115
127
  id: task.id,
116
128
  body,
117
129
  });
118
- if (['failed', 'success'].includes(body.status) &&
130
+ if (['failed', 'succeeded'].includes(body.status) &&
119
131
  task.is_scheduled_with__cron_expression != null) {
120
132
  await this.client.post({
121
133
  resource: 'task',
@@ -148,21 +160,21 @@ class Worker {
148
160
  return;
149
161
  }
150
162
  const result = await tx.executeSql(`SELECT ${selectColumns}
151
- FROM task AS t
152
- WHERE
153
- t."is executed by-handler" IN (${binds}) AND
154
- t."status" = 'pending' AND
155
- t."attempt count" <= t."attempt limit" AND
156
- (
157
- t."is scheduled to execute on-time" IS NULL OR
158
- t."is scheduled to execute on-time" <= CURRENT_TIMESTAMP + INTERVAL '${Math.ceil(this.interval / 1000)} second'
159
- )
160
- ORDER BY
161
- t."is scheduled to execute on-time" ASC,
162
- t."priority" DESC,
163
- t."id" ASC
164
- LIMIT ${Math.max(this.concurrency - this.executing, 0)}
165
- FOR UPDATE SKIP LOCKED`, handlerNames);
163
+ FROM task AS t
164
+ WHERE
165
+ t."is executed by-handler" IN (${binds}) AND
166
+ t."status" = 'queued' AND
167
+ t."attempt count" <= t."attempt limit" AND
168
+ (
169
+ t."is scheduled to execute on-time" IS NULL OR
170
+ t."is scheduled to execute on-time" <= CURRENT_TIMESTAMP + INTERVAL '${Math.ceil(this.interval / 1000)} second'
171
+ )
172
+ ORDER BY
173
+ t."is scheduled to execute on-time" ASC,
174
+ t."priority" DESC,
175
+ t."id" ASC
176
+ LIMIT ${Math.max(this.concurrency - this.executing, 0)}
177
+ FOR UPDATE SKIP LOCKED`, handlerNames);
166
178
  if (result.rows.length === 0) {
167
179
  return;
168
180
  }
@@ -1 +1 @@
1
- {"version":3,"file":"worker.js","sourceRoot":"","sources":["../../src/tasks/worker.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"worker.js","sourceRoot":"","sources":["../../src/tasks/worker.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@balena/pinejs",
3
- "version": "16.2.0-build-joshbwlng-tasks-56c035f7e142216b5cf56fc7d861ce4b51157a41-1",
3
+ "version": "16.2.0-build-joshbwlng-tasks-009b08b1f157611c22f2425c25f905d5a59aaabe-1",
4
4
  "main": "out/server-glue/module",
5
5
  "type": "commonjs",
6
6
  "repository": "git@github.com:balena-io/pinejs.git",
@@ -147,6 +147,6 @@
147
147
  "recursive": true
148
148
  },
149
149
  "versionist": {
150
- "publishedAt": "2024-04-25T23:07:34.017Z"
150
+ "publishedAt": "2024-04-30T05:37:16.724Z"
151
151
  }
152
152
  }
@@ -5,7 +5,7 @@ import type * as Db from '../database-layer/db';
5
5
  import { BadRequestError } from '../sbvr-api/errors';
6
6
  import { addPureHook } from '../sbvr-api/hooks';
7
7
  import { PinejsClient } from '../sbvr-api/sbvr-utils';
8
- import type { sbvrUtils } from '../server-glue/module';
8
+ import * as sbvrUtils from '../sbvr-api/sbvr-utils';
9
9
  import { ajv, apiRoot, channel } from './common';
10
10
  import type { TaskHandler } from './types';
11
11
  import { Worker } from './worker';
@@ -30,22 +30,85 @@ export const config = {
30
30
  // Only poll or execute on triggers if worker is not already at max concurrency
31
31
  async function createTrigger(tx: Db.Tx): Promise<void> {
32
32
  await tx.executeSql(`
33
- CREATE OR REPLACE FUNCTION notify_task_insert()
34
- RETURNS TRIGGER AS $$
35
- BEGIN
36
- PERFORM pg_notify('${channel}', NEW.id::text);
37
- RETURN NEW;
38
- END;
39
- $$ LANGUAGE plpgsql;
40
- `);
41
-
42
- // Only trigger if task is pending and not scheduled
33
+ CREATE OR REPLACE FUNCTION notify_task_insert()
34
+ RETURNS TRIGGER AS $$
35
+ BEGIN
36
+ PERFORM pg_notify('${channel}', NEW.id::text);
37
+ RETURN NEW;
38
+ END;
39
+ $$ LANGUAGE plpgsql;
40
+ `);
41
+
42
+ // Only trigger if task is queued and not scheduled
43
43
  await tx.executeSql(`
44
- CREATE OR REPLACE TRIGGER task_insert_trigger
45
- AFTER INSERT ON task
46
- FOR EACH ROW WHEN (NEW.status = 'pending' AND NEW."is scheduled to execute on-time" IS NULL)
47
- EXECUTE FUNCTION notify_task_insert();
48
- `);
44
+ CREATE OR REPLACE TRIGGER task_insert_trigger
45
+ AFTER INSERT ON task
46
+ FOR EACH ROW WHEN (NEW.status = 'queued' AND NEW."is scheduled to execute on-time" IS NULL)
47
+ EXECUTE FUNCTION notify_task_insert();
48
+ `);
49
+ }
50
+
51
+ // Create indexes
52
+ async function createIndexes(tx: Db.Tx): Promise<void> {
53
+ // Partial index for polling
54
+ await tx.executeSql(`
55
+ CREATE INDEX IF NOT EXISTS idx_task_poll ON task USING btree (
56
+ "is executed by-handler",
57
+ "is scheduled to execute on-time" ASC,
58
+ "priority" DESC,
59
+ "id" ASC
60
+ ) WHERE status = 'queued';
61
+ `);
62
+
63
+ // Partial index used to adjust priority based on actor
64
+ await tx.executeSql(`
65
+ CREATE INDEX IF NOT EXISTS idx_task_queued ON task (
66
+ "id",
67
+ "is created by-actor"
68
+ ) WHERE status = 'queued';
69
+ `);
70
+ }
71
+
72
+ // Check if a task should be given priority
73
+ // This is used to balance the load across actors
74
+ // by giving priority to actors with less tasks in the queue
75
+ // when another actor is crossing a percentage threshold of queued tasks
76
+ // This is to prevent a single actor from hogging the queue
77
+ async function adjustPriority(
78
+ actor: number,
79
+ priority: number,
80
+ ): Promise<number> {
81
+ const result = await (sbvrUtils.db.executeSql(
82
+ `SELECT "is created by-actor", COUNT("id") AS task_count
83
+ FROM (
84
+ SELECT "id", "is created by-actor"
85
+ FROM task
86
+ WHERE "status" = 'queued'
87
+ ORDER BY "id" DESC
88
+ LIMIT 100
89
+ ) AS recent_tasks
90
+ GROUP BY "is created by-actor"
91
+ ORDER BY task_count DESC;
92
+ `,
93
+ ) as Promise<{
94
+ rowsAffected: number;
95
+ rows: Array<{
96
+ 'is created by-actor': number;
97
+ task_count: string;
98
+ }>;
99
+ }>);
100
+
101
+ // Increase the priority of this task if another actor is filling up the queue
102
+ if (
103
+ result.rows.some(
104
+ (row) =>
105
+ parseInt(row.task_count, 10) >= 49 &&
106
+ row['is created by-actor'] !== actor,
107
+ )
108
+ ) {
109
+ return priority + 1;
110
+ }
111
+ return priority;
49
112
  }
50
113
 
51
114
  let worker: Worker | null = null;
@@ -58,6 +121,9 @@ export async function setup(db: Db.Database, tx: Db.Tx): Promise<void> {
58
121
  // Create trigger function if it doesn't exist
59
122
  await createTrigger(tx);
60
123
 
124
+ // Create indexes if they don't exist
125
+ await createIndexes(tx);
126
+
61
127
  const client = new PinejsClient({
62
128
  apiPrefix: `/${apiRoot}/`,
63
129
  });
@@ -76,11 +142,17 @@ export async function setup(db: Db.Database, tx: Db.Tx): Promise<void> {
76
142
  }
77
143
 
78
144
  // Set defaults
79
- request.values.status = 'pending';
145
+ request.values.status = 'queued';
80
146
  request.values.attempt_count = 0;
81
147
  request.values.priority ??= 1;
82
148
  request.values.attempt_limit ??= 1;
83
149
 
150
+ // Possibly adjust priority based on actor
151
+ request.values.priority = await adjustPriority(
152
+ request.values.is_created_by__actor,
153
+ request.values.priority,
154
+ );
155
+
84
156
  // Set scheduled start time using cron expression if provided
85
157
  if (
86
158
  request.values.is_scheduled_with__cron_expression != null &&
@@ -45,7 +45,7 @@ Fact type: task is scheduled to execute on time
45
45
  Necessity: each task is scheduled to execute on at most one time
46
46
  Fact type: task has status
47
47
  Necessity: each task has exactly one status
48
- Definition: "pending" or "cancelled" or "success" or "failed"
48
+ Definition: "queued" or "cancelled" or "succeeded" or "failed"
49
49
  Fact type: task started on time
50
50
  Necessity: each task started on at most one time
51
51
  Fact type: task ended on time
@@ -4,9 +4,9 @@ import type * as Db from '../database-layer/db';
4
4
  import type { PinejsClient } from '../sbvr-api/sbvr-utils';
5
5
 
6
6
  export const taskStatuses = [
7
- 'pending',
7
+ 'queued',
8
8
  'cancelled',
9
- 'success',
9
+ 'succeeded',
10
10
  'failed',
11
11
  ] as const;
12
12
  export type TaskStatus = (typeof taskStatuses)[number];
@@ -1,6 +1,7 @@
1
1
  import type { AnyObject } from 'pinejs-client-core';
2
2
  import { tasks as tasksEnv } from '../config-loader/env';
3
3
  import type * as Db from '../database-layer/db';
4
+ import { TransactionClosedError } from '../database-layer/db';
4
5
  import * as permissions from '../sbvr-api/permissions';
5
6
  import { PinejsClient } from '../sbvr-api/sbvr-utils';
6
7
  import { sbvrUtils } from '../server-glue/module';
@@ -80,24 +81,34 @@ export class Worker {
80
81
  }
81
82
 
82
83
  // Execute handler
83
- await tx.executeSql(`SAVEPOINT task_${task.id}`);
84
- const result = await handler.fn({
85
- api: new PinejsClient({
86
- passthrough: {
87
- tx,
88
- },
89
- }),
90
- params: task.is_executed_with__parameter_set ?? {},
91
- tx,
92
- });
93
- if (result.status === 'success') {
94
- await tx.executeSql(`RELEASE SAVEPOINT task_${task.id}`);
95
- } else {
96
- await tx.executeSql(`ROLLBACK TO SAVEPOINT task_${task.id}`);
84
+ let status: TaskStatus = 'queued';
85
+ let error: string | undefined;
86
+ try {
87
+ await sbvrUtils.db.transaction(async (handlerTx) => {
88
+ const results = await handler.fn({
89
+ api: new PinejsClient({
90
+ passthrough: {
91
+ tx: handlerTx,
92
+ },
93
+ }),
94
+ params: task.is_executed_with__parameter_set ?? {},
95
+ tx: handlerTx,
96
+ });
97
+ status = results.status;
98
+ error = results.error;
99
+ if (results.status !== 'succeeded' && !handlerTx.isClosed()) {
100
+ await handlerTx.rollback();
101
+ }
102
+ });
103
+ } catch (err) {
104
+ // Ignore closed/rollback errors
105
+ if (!(err instanceof TransactionClosedError)) {
106
+ throw err;
107
+ }
108
+ } finally {
109
+ // Update task with results
110
+ await this.finalize(tx, task, startedOnTime, status, error);
97
111
  }
98
-
99
- // Update task with results
100
- await this.finalize(tx, task, startedOnTime, result.status, result.error);
101
112
  } catch (err) {
102
113
  // This shouldn't happen, but if it does we want to log and kill the process
103
114
  console.error('Task execution failed:', err);
@@ -127,7 +138,7 @@ export class Worker {
127
138
  // Re-enqueue if the task failed but has retries left, remember that
128
139
  // attemptCount includes the initial attempt while attempt_limit does not
129
140
  if (status === 'failed' && attemptCount < task.attempt_limit) {
130
- body.status = 'pending';
141
+ body.status = 'queued';
131
142
 
132
143
  // Schedule next attempt using exponential backoff
133
144
  body.is_scheduled_to_execute_on__time =
@@ -148,7 +159,7 @@ export class Worker {
148
159
  // Create new task with same configuration if previous
149
160
  // iteration completed and has a cron expression
150
161
  if (
151
- ['failed', 'success'].includes(body.status) &&
162
+ ['failed', 'succeeded'].includes(body.status) &&
152
163
  task.is_scheduled_with__cron_expression != null
153
164
  ) {
154
165
  await this.client.post({
@@ -189,21 +200,21 @@ export class Worker {
189
200
 
190
201
  const result = await tx.executeSql(
191
202
  `SELECT ${selectColumns}
192
- FROM task AS t
193
- WHERE
194
- t."is executed by-handler" IN (${binds}) AND
195
- t."status" = 'pending' AND
196
- t."attempt count" <= t."attempt limit" AND
197
- (
198
- t."is scheduled to execute on-time" IS NULL OR
199
- t."is scheduled to execute on-time" <= CURRENT_TIMESTAMP + INTERVAL '${Math.ceil(this.interval / 1000)} second'
200
- )
201
- ORDER BY
202
- t."is scheduled to execute on-time" ASC,
203
- t."priority" DESC,
204
- t."id" ASC
205
- LIMIT ${Math.max(this.concurrency - this.executing, 0)}
206
- FOR UPDATE SKIP LOCKED`,
203
+ FROM task AS t
204
+ WHERE
205
+ t."is executed by-handler" IN (${binds}) AND
206
+ t."status" = 'queued' AND
207
+ t."attempt count" <= t."attempt limit" AND
208
+ (
209
+ t."is scheduled to execute on-time" IS NULL OR
210
+ t."is scheduled to execute on-time" <= CURRENT_TIMESTAMP + INTERVAL '${Math.ceil(this.interval / 1000)} second'
211
+ )
212
+ ORDER BY
213
+ t."is scheduled to execute on-time" ASC,
214
+ t."priority" DESC,
215
+ t."id" ASC
216
+ LIMIT ${Math.max(this.concurrency - this.executing, 0)}
217
+ FOR UPDATE SKIP LOCKED`,
207
218
  handlerNames,
208
219
  );
209
220
  if (result.rows.length === 0) {