@balena/pinejs 16.2.0-build-joshbwlng-tasks-cd1aff5f4bbfacaad189b013578d5cbee51c3932-1 → 16.2.0-build-joshbwlng-tasks-a83c83b4c78803915d0cb6297cc8cc1862622d08-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.
package/.husky/pre-commit CHANGED
@@ -1,4 +1,2 @@
1
- #!/usr/bin/env sh
2
- . "$(dirname -- "$0")/_/husky.sh"
3
1
 
4
2
  npx --no lint-staged
@@ -1,14 +1,6 @@
1
1
  - commits:
2
- - subject: Organize code
3
- hash: cd1aff5f4bbfacaad189b013578d5cbee51c3932
4
- body: ""
5
- footer:
6
- Change-type: patch
7
- change-type: patch
8
- author: Josh Bowling
9
- nested: []
10
2
  - subject: Add async tasks
11
- hash: 2b1a04b883e932516582ba8c9f0fc4d5913d5335
3
+ hash: a83c83b4c78803915d0cb6297cc8cc1862622d08
12
4
  body: ""
13
5
  footer:
14
6
  Change-type: minor
@@ -17,7 +9,33 @@
17
9
  nested: []
18
10
  version: 16.2.0
19
11
  title: ""
20
- date: 2024-04-10T23:12:22.210Z
12
+ date: 2024-04-15T01:28:02.918Z
13
+ - commits:
14
+ - subject: Update dependency husky to v9
15
+ hash: 715d2dd993591d449bca7ece48f069ed6994c8c7
16
+ body: |
17
+ Update husky from 8.0.3 to 9.0.11
18
+ footer:
19
+ Change-type: patch
20
+ change-type: patch
21
+ author: Self-hosted Renovate Bot
22
+ nested: []
23
+ version: 16.1.2
24
+ title: ""
25
+ date: 2024-04-14T04:09:27.077Z
26
+ - commits:
27
+ - subject: Update dependency @balena/lint to v8
28
+ hash: 02ba2563aa4ac82ad90accc30534f744c00a0c16
29
+ body: |
30
+ Update @balena/lint from 7.3.0 to 8.0.0
31
+ footer:
32
+ Change-type: patch
33
+ change-type: patch
34
+ author: Self-hosted Renovate Bot
35
+ nested: []
36
+ version: 16.1.1
37
+ title: ""
38
+ date: 2024-04-11T22:45:27.398Z
21
39
  - commits:
22
40
  - subject: Add support for prettifying index constraint errors with their
23
41
  description
package/CHANGELOG.md CHANGED
@@ -5,11 +5,20 @@ 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-10)
8
+ ## (2024-04-15)
9
9
 
10
- * Organize code [Josh Bowling]
11
10
  * Add async tasks [Josh Bowling]
12
11
 
12
+ # v16.1.2
13
+ ## (2024-04-14)
14
+
15
+ * Update dependency husky to v9 [Self-hosted Renovate Bot]
16
+
17
+ # v16.1.1
18
+ ## (2024-04-11)
19
+
20
+ * Update dependency @balena/lint to v8 [Self-hosted Renovate Bot]
21
+
13
22
  # v16.1.0
14
23
  ## (2024-04-02)
15
24
 
@@ -8,9 +8,9 @@ export declare class Worker {
8
8
  private executing;
9
9
  constructor(client: PinejsClient);
10
10
  private canExecute;
11
- private poll;
12
- start(): void;
13
11
  private execute;
12
+ private finalize;
14
13
  private getNextAttemptTime;
15
- private update;
14
+ private poll;
15
+ start(): void;
16
16
  }
@@ -52,73 +52,18 @@ class Worker {
52
52
  canExecute() {
53
53
  return (this.executing < this.concurrency && Object.keys(this.handlers).length > 0);
54
54
  }
55
- poll() {
56
- let executed = false;
57
- const names = Object.keys(this.handlers);
58
- const binds = names.map((_, index) => `$${index + 1}`).join(', ');
59
- module_1.sbvrUtils.db
60
- .transaction(async (tx) => {
61
- if (!this.canExecute()) {
62
- return;
63
- }
64
- const result = await tx.executeSql(`SELECT ${selectColumns}
65
- FROM task AS t
66
- WHERE
67
- t."is executed by-handler" IN (${binds}) AND
68
- t."status" = 'pending' AND
69
- t."attempt count" <= t."attempt limit" AND
70
- (
71
- t."is scheduled to execute on-time" IS NULL OR
72
- t."is scheduled to execute on-time" <= CURRENT_TIMESTAMP + INTERVAL '${Math.ceil(this.interval / 1000)} second'
73
- )
74
- ORDER BY
75
- t."is scheduled to execute on-time" ASC,
76
- t."priority" DESC,
77
- t."id" ASC
78
- LIMIT ${Math.max(this.concurrency - this.executing, 0)}
79
- FOR UPDATE SKIP LOCKED`, names);
80
- if (result.rows.length === 0) {
81
- return;
82
- }
83
- await Promise.all(result.rows.map(async (row) => {
84
- await this.execute(tx, row);
85
- }));
86
- executed = true;
87
- })
88
- .catch((err) => {
89
- console.error('Failed polling for tasks:', err);
90
- })
91
- .finally(() => {
92
- setTimeout(() => this.poll(), executed ? 0 : this.interval);
93
- });
94
- }
95
- start() {
96
- module_1.sbvrUtils.db.on?.('notification', async (msg) => {
97
- if (this.canExecute()) {
98
- await module_1.sbvrUtils.db.transaction(async (tx) => {
99
- const result = await tx.executeSql(`SELECT ${selectColumns} FROM task AS t WHERE id = $1 FOR UPDATE SKIP LOCKED`, [msg.payload]);
100
- if (result.rows.length > 0) {
101
- await this.execute(tx, result.rows[0]);
102
- }
103
- });
104
- }
105
- }, {
106
- channel: common_1.channel,
107
- });
108
- this.poll();
109
- }
110
55
  async execute(tx, task) {
111
56
  this.executing++;
112
57
  try {
113
58
  const handler = this.handlers[task.is_executed_by__handler];
114
59
  const startedOnTime = new Date();
115
60
  if (handler == null) {
116
- await this.update(tx, task, startedOnTime, 'failed', 'Matching task handler not found');
61
+ await this.finalize(tx, task, startedOnTime, 'failed', 'Matching task handler not found');
117
62
  return;
118
63
  }
119
64
  if (handler.validate != null &&
120
65
  !handler.validate(task.is_executed_with__parameter_set)) {
121
- await this.update(tx, task, startedOnTime, 'failed', `Invalid parameter set: ${common_1.ajv.errorsText(handler.validate.errors)}`);
66
+ await this.finalize(tx, task, startedOnTime, 'failed', `Invalid parameter set: ${common_1.ajv.errorsText(handler.validate.errors)}`);
122
67
  return;
123
68
  }
124
69
  const result = await handler.fn({
@@ -130,7 +75,7 @@ class Worker {
130
75
  params: task.is_executed_with__parameter_set ?? {},
131
76
  tx,
132
77
  });
133
- await this.update(tx, task, startedOnTime, result.status, result.error);
78
+ await this.finalize(tx, task, startedOnTime, result.status, result.error);
134
79
  }
135
80
  catch (err) {
136
81
  console.error('Task execution failed:', err);
@@ -140,11 +85,7 @@ class Worker {
140
85
  this.executing--;
141
86
  }
142
87
  }
143
- getNextAttemptTime(attempt) {
144
- const delay = Math.ceil(Math.exp(Math.min(10, attempt))) * 1000;
145
- return new Date(Date.now() + delay);
146
- }
147
- async update(tx, task, startedOnTime, status, errorMessage) {
88
+ async finalize(tx, task, startedOnTime, status, errorMessage) {
148
89
  const attemptCount = task.attempt_count + 1;
149
90
  const body = {
150
91
  started_on__time: startedOnTime,
@@ -186,6 +127,65 @@ class Worker {
186
127
  });
187
128
  }
188
129
  }
130
+ getNextAttemptTime(attempt) {
131
+ const delay = Math.ceil(Math.exp(Math.min(10, attempt))) * 1000;
132
+ return new Date(Date.now() + delay);
133
+ }
134
+ poll() {
135
+ let executed = false;
136
+ const handlerNames = Object.keys(this.handlers);
137
+ const binds = handlerNames.map((_, index) => `$${index + 1}`).join(', ');
138
+ module_1.sbvrUtils.db
139
+ .transaction(async (tx) => {
140
+ if (!this.canExecute()) {
141
+ return;
142
+ }
143
+ const result = await tx.executeSql(`SELECT ${selectColumns}
144
+ FROM task AS t
145
+ WHERE
146
+ t."is executed by-handler" IN (${binds}) AND
147
+ t."status" = 'pending' AND
148
+ t."attempt count" <= t."attempt limit" AND
149
+ (
150
+ t."is scheduled to execute on-time" IS NULL OR
151
+ t."is scheduled to execute on-time" <= CURRENT_TIMESTAMP + INTERVAL '${Math.ceil(this.interval / 1000)} second'
152
+ )
153
+ ORDER BY
154
+ t."is scheduled to execute on-time" ASC,
155
+ t."priority" DESC,
156
+ t."id" ASC
157
+ LIMIT ${Math.max(this.concurrency - this.executing, 0)}
158
+ FOR UPDATE SKIP LOCKED`, handlerNames);
159
+ if (result.rows.length === 0) {
160
+ return;
161
+ }
162
+ await Promise.all(result.rows.map(async (row) => {
163
+ await this.execute(tx, row);
164
+ }));
165
+ executed = true;
166
+ })
167
+ .catch((err) => {
168
+ console.error('Failed polling for tasks:', err);
169
+ })
170
+ .finally(() => {
171
+ setTimeout(() => this.poll(), executed ? 0 : this.interval);
172
+ });
173
+ }
174
+ start() {
175
+ module_1.sbvrUtils.db.on?.('notification', async (msg) => {
176
+ if (this.canExecute()) {
177
+ await module_1.sbvrUtils.db.transaction(async (tx) => {
178
+ const result = await tx.executeSql(`SELECT ${selectColumns} FROM task AS t WHERE id = $1 FOR UPDATE SKIP LOCKED`, [msg.payload]);
179
+ if (result.rows.length > 0) {
180
+ await this.execute(tx, result.rows[0]);
181
+ }
182
+ });
183
+ }
184
+ }, {
185
+ channel: common_1.channel,
186
+ });
187
+ this.poll();
188
+ }
189
189
  }
190
190
  exports.Worker = Worker;
191
191
  //# sourceMappingURL=worker.js.map
@@ -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-cd1aff5f4bbfacaad189b013578d5cbee51c3932-1",
3
+ "version": "16.2.0-build-joshbwlng-tasks-a83c83b4c78803915d0cb6297cc8cc1862622d08-1",
4
4
  "main": "out/server-glue/module",
5
5
  "type": "commonjs",
6
6
  "repository": "git@github.com:balena-io/pinejs.git",
@@ -12,7 +12,7 @@
12
12
  },
13
13
  "scripts": {
14
14
  "prepublish": "require-npm4-to-publish",
15
- "prepare": "node -e \"try { require('husky').install() } catch (e) {if (e.code !== 'MODULE_NOT_FOUND') throw e}\" && npm run build",
15
+ "prepare": "node -e \"try { (await import('husky')).default() } catch (e) { if (e.code !== 'ERR_MODULE_NOT_FOUND') throw e }\" --input-type module && npm run build",
16
16
  "build": "grunt build",
17
17
  "webpack-browser": "grunt browser",
18
18
  "webpack-module": "grunt module",
@@ -65,7 +65,7 @@
65
65
  "typed-error": "^3.2.2"
66
66
  },
67
67
  "devDependencies": {
68
- "@balena/lint": "^7.2.4",
68
+ "@balena/lint": "^8.0.0",
69
69
  "@faker-js/faker": "^8.3.1",
70
70
  "@types/busboy": "^1.5.3",
71
71
  "@types/chai": "^4.3.11",
@@ -90,7 +90,7 @@
90
90
  "grunt-text-replace": "^0.4.0",
91
91
  "grunt-ts": "^6.0.0-beta.22",
92
92
  "grunt-webpack": "^6.0.0",
93
- "husky": "^8.0.3",
93
+ "husky": "^9.0.0",
94
94
  "json-schema-to-ts": "^3.0.1",
95
95
  "lint-staged": "^15.2.0",
96
96
  "load-grunt-tasks": "^5.1.0",
@@ -147,6 +147,6 @@
147
147
  "recursive": true
148
148
  },
149
149
  "versionist": {
150
- "publishedAt": "2024-04-10T23:12:22.905Z"
150
+ "publishedAt": "2024-04-15T01:28:03.598Z"
151
151
  }
152
152
  }
@@ -37,93 +37,22 @@ export class Worker {
37
37
  this.interval = tasksEnv.queueIntervalMS;
38
38
  }
39
39
 
40
+ // Check if instance can execute more tasks
40
41
  private canExecute(): boolean {
41
42
  return (
42
43
  this.executing < this.concurrency && Object.keys(this.handlers).length > 0
43
44
  );
44
45
  }
45
46
 
46
- private poll(): void {
47
- let executed = false;
48
- const names = Object.keys(this.handlers);
49
- const binds = names.map((_, index) => `$${index + 1}`).join(', ');
50
- sbvrUtils.db
51
- .transaction(async (tx) => {
52
- if (!this.canExecute()) {
53
- return;
54
- }
55
-
56
- const result = await tx.executeSql(
57
- `SELECT ${selectColumns}
58
- FROM task AS t
59
- WHERE
60
- t."is executed by-handler" IN (${binds}) AND
61
- t."status" = 'pending' AND
62
- t."attempt count" <= t."attempt limit" AND
63
- (
64
- t."is scheduled to execute on-time" IS NULL OR
65
- t."is scheduled to execute on-time" <= CURRENT_TIMESTAMP + INTERVAL '${Math.ceil(this.interval / 1000)} second'
66
- )
67
- ORDER BY
68
- t."is scheduled to execute on-time" ASC,
69
- t."priority" DESC,
70
- t."id" ASC
71
- LIMIT ${Math.max(this.concurrency - this.executing, 0)}
72
- FOR UPDATE SKIP LOCKED`,
73
- names,
74
- );
75
- if (result.rows.length === 0) {
76
- return;
77
- }
78
-
79
- // Tasks found, execute them in parallel
80
- await Promise.all(
81
- result.rows.map(async (row) => {
82
- await this.execute(tx, row as PartialTask);
83
- }),
84
- );
85
- executed = true;
86
- })
87
- .catch((err) => {
88
- console.error('Failed polling for tasks:', err);
89
- })
90
- .finally(() => {
91
- setTimeout(() => this.poll(), executed ? 0 : this.interval);
92
- });
93
- }
94
-
95
- // Start listening and polling for tasks
96
- public start() {
97
- sbvrUtils.db.on?.(
98
- 'notification',
99
- async (msg) => {
100
- if (this.canExecute()) {
101
- await sbvrUtils.db.transaction(async (tx) => {
102
- const result = await tx.executeSql(
103
- `SELECT ${selectColumns} FROM task AS t WHERE id = $1 FOR UPDATE SKIP LOCKED`,
104
- [msg.payload],
105
- );
106
- if (result.rows.length > 0) {
107
- await this.execute(tx, result.rows[0] as PartialTask);
108
- }
109
- });
110
- }
111
- },
112
- {
113
- channel,
114
- },
115
- );
116
- this.poll();
117
- }
118
-
47
+ // Execute a task
119
48
  private async execute(tx: Db.Tx, task: PartialTask): Promise<void> {
120
49
  this.executing++;
121
50
  try {
122
- // Get the handler
51
+ // Get specified handler
123
52
  const handler = this.handlers[task.is_executed_by__handler];
124
53
  const startedOnTime = new Date();
125
54
  if (handler == null) {
126
- await this.update(
55
+ await this.finalize(
127
56
  tx,
128
57
  task,
129
58
  startedOnTime,
@@ -140,7 +69,7 @@ export class Worker {
140
69
  handler.validate != null &&
141
70
  !handler.validate(task.is_executed_with__parameter_set)
142
71
  ) {
143
- await this.update(
72
+ await this.finalize(
144
73
  tx,
145
74
  task,
146
75
  startedOnTime,
@@ -150,7 +79,7 @@ export class Worker {
150
79
  return;
151
80
  }
152
81
 
153
- // Execute the handler
82
+ // Execute handler
154
83
  const result = await handler.fn({
155
84
  api: new PinejsClient({
156
85
  passthrough: {
@@ -161,10 +90,10 @@ export class Worker {
161
90
  tx,
162
91
  });
163
92
 
164
- // Update the task with the results
165
- await this.update(tx, task, startedOnTime, result.status, result.error);
93
+ // Update task with results
94
+ await this.finalize(tx, task, startedOnTime, result.status, result.error);
166
95
  } catch (err) {
167
- // This shouldn't normally happen, but if it does, we want to log it and kill the process
96
+ // This shouldn't happen, but if it does we want to log and kill the process
168
97
  console.error('Task execution failed:', err);
169
98
  process.exit(1);
170
99
  } finally {
@@ -172,12 +101,8 @@ export class Worker {
172
101
  }
173
102
  }
174
103
 
175
- private getNextAttemptTime(attempt: number): Date | null {
176
- const delay = Math.ceil(Math.exp(Math.min(10, attempt))) * 1000;
177
- return new Date(Date.now() + delay);
178
- }
179
-
180
- private async update(
104
+ // Update task and schedule next attempt if needed
105
+ private async finalize(
181
106
  tx: Db.Tx,
182
107
  task: PartialTask,
183
108
  startedOnTime: Date,
@@ -238,4 +163,84 @@ export class Worker {
238
163
  });
239
164
  }
240
165
  }
166
+
167
+ // Calculate next attempt time using exponential backoff
168
+ private getNextAttemptTime(attempt: number): Date | null {
169
+ const delay = Math.ceil(Math.exp(Math.min(10, attempt))) * 1000;
170
+ return new Date(Date.now() + delay);
171
+ }
172
+
173
+ // Poll for tasks to execute
174
+ private poll(): void {
175
+ let executed = false;
176
+ const handlerNames = Object.keys(this.handlers);
177
+ const binds = handlerNames.map((_, index) => `$${index + 1}`).join(', ');
178
+ sbvrUtils.db
179
+ .transaction(async (tx) => {
180
+ if (!this.canExecute()) {
181
+ return;
182
+ }
183
+
184
+ const result = await tx.executeSql(
185
+ `SELECT ${selectColumns}
186
+ FROM task AS t
187
+ WHERE
188
+ t."is executed by-handler" IN (${binds}) AND
189
+ t."status" = 'pending' AND
190
+ t."attempt count" <= t."attempt limit" AND
191
+ (
192
+ t."is scheduled to execute on-time" IS NULL OR
193
+ t."is scheduled to execute on-time" <= CURRENT_TIMESTAMP + INTERVAL '${Math.ceil(this.interval / 1000)} second'
194
+ )
195
+ ORDER BY
196
+ t."is scheduled to execute on-time" ASC,
197
+ t."priority" DESC,
198
+ t."id" ASC
199
+ LIMIT ${Math.max(this.concurrency - this.executing, 0)}
200
+ FOR UPDATE SKIP LOCKED`,
201
+ handlerNames,
202
+ );
203
+ if (result.rows.length === 0) {
204
+ return;
205
+ }
206
+
207
+ // Tasks found, execute them in parallel
208
+ await Promise.all(
209
+ result.rows.map(async (row) => {
210
+ await this.execute(tx, row as PartialTask);
211
+ }),
212
+ );
213
+ executed = true;
214
+ })
215
+ .catch((err) => {
216
+ console.error('Failed polling for tasks:', err);
217
+ })
218
+ .finally(() => {
219
+ setTimeout(() => this.poll(), executed ? 0 : this.interval);
220
+ });
221
+ }
222
+
223
+ // Start listening and polling for tasks
224
+ public start(): void {
225
+ sbvrUtils.db.on?.(
226
+ 'notification',
227
+ async (msg) => {
228
+ if (this.canExecute()) {
229
+ await sbvrUtils.db.transaction(async (tx) => {
230
+ const result = await tx.executeSql(
231
+ `SELECT ${selectColumns} FROM task AS t WHERE id = $1 FOR UPDATE SKIP LOCKED`,
232
+ [msg.payload],
233
+ );
234
+ if (result.rows.length > 0) {
235
+ await this.execute(tx, result.rows[0] as PartialTask);
236
+ }
237
+ });
238
+ }
239
+ },
240
+ {
241
+ channel,
242
+ },
243
+ );
244
+ this.poll();
245
+ }
241
246
  }