@goatlab/tasks-adapter-gcp 0.2.3 → 0.3.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.
|
@@ -11,15 +11,16 @@ const defaultBackoffSettings = {
|
|
|
11
11
|
maxRetryDelayMillis: 3600,
|
|
12
12
|
initialRpcTimeoutMillis: 6000
|
|
13
13
|
};
|
|
14
|
+
// Pre-calculated constants
|
|
15
|
+
const MS_TO_MINUTES = 1 / 60000;
|
|
14
16
|
function getScheduledInfo(scheduled) {
|
|
15
17
|
if (scheduled === 0) {
|
|
16
18
|
return {
|
|
17
19
|
minutesUntil: 0
|
|
18
20
|
};
|
|
19
21
|
}
|
|
20
|
-
|
|
21
|
-
const
|
|
22
|
-
const minutesUntil = Math.floor((scheduledMs - nowMs) / 1000 / 60);
|
|
22
|
+
// Avoid multiple multiplication - calculate difference directly
|
|
23
|
+
const minutesUntil = Math.floor((scheduled * 1000 - Date.now()) * MS_TO_MINUTES);
|
|
23
24
|
return { minutesUntil };
|
|
24
25
|
}
|
|
25
26
|
class CloudTaskConnector {
|
|
@@ -48,39 +49,21 @@ class CloudTaskConnector {
|
|
|
48
49
|
async addTask({ task, queueName = 'default', backoffSettings = defaultBackoffSettings, baseUrl }) {
|
|
49
50
|
(0, js_utils_1.assert)(task.httpRequest, `task.httpRequest property is required`);
|
|
50
51
|
const { url } = task.httpRequest;
|
|
51
|
-
const parseUrl = async (urlString) => {
|
|
52
|
-
if (!urlString) {
|
|
53
|
-
return;
|
|
54
|
-
}
|
|
55
|
-
// urlService.getBackendUrl({
|
|
56
|
-
// useIP: true
|
|
57
|
-
// })
|
|
58
|
-
return new URL(urlString, baseUrl);
|
|
59
|
-
};
|
|
60
52
|
(0, js_utils_1.assert)(url, 'Task URL is required');
|
|
61
|
-
// Parse URL to point to the correct backend
|
|
62
|
-
const parsedURL =
|
|
53
|
+
// Parse URL to point to the correct backend - simplified without async wrapper
|
|
54
|
+
const parsedURL = new URL(url, baseUrl);
|
|
63
55
|
(0, js_utils_1.assert)(parsedURL, 'Task URL is invalid');
|
|
64
56
|
const client = await this.getCloudTasksClient();
|
|
65
57
|
const parent = client.queuePath(this.gcpProject, this.location, queueName);
|
|
66
|
-
//
|
|
67
|
-
|
|
68
|
-
task = {
|
|
69
|
-
...task,
|
|
70
|
-
name: `${parent}/tasks/${task.name}`
|
|
71
|
-
};
|
|
72
|
-
}
|
|
73
|
-
task = {
|
|
74
|
-
...task,
|
|
75
|
-
httpRequest: {
|
|
76
|
-
...task.httpRequest,
|
|
77
|
-
url: parsedURL.href
|
|
78
|
-
}
|
|
79
|
-
};
|
|
80
|
-
task = {
|
|
58
|
+
// Build the task object in one go to avoid multiple spreads
|
|
59
|
+
const finalTask = {
|
|
81
60
|
...task,
|
|
61
|
+
name: task.name && !task.name.startsWith(parent)
|
|
62
|
+
? `${parent}/tasks/${task.name}`
|
|
63
|
+
: task.name,
|
|
82
64
|
httpRequest: {
|
|
83
65
|
...task.httpRequest,
|
|
66
|
+
url: parsedURL.href,
|
|
84
67
|
headers: {
|
|
85
68
|
'content-type': 'application/octet-stream'
|
|
86
69
|
},
|
|
@@ -111,7 +94,7 @@ class CloudTaskConnector {
|
|
|
111
94
|
// }
|
|
112
95
|
const [response] = await client.createTask({
|
|
113
96
|
parent,
|
|
114
|
-
task
|
|
97
|
+
task: finalTask
|
|
115
98
|
}, {
|
|
116
99
|
retry: {
|
|
117
100
|
retryCodes: [
|
|
@@ -151,10 +134,11 @@ class CloudTaskConnector {
|
|
|
151
134
|
* @returns The decrypted body as a Record<string, Primitive>.
|
|
152
135
|
*/
|
|
153
136
|
decryptBody(body) {
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
137
|
+
if (!body) {
|
|
138
|
+
return {};
|
|
139
|
+
}
|
|
140
|
+
// Direct parsing without intermediate buffer conversion for strings
|
|
141
|
+
const bodyJSON = JSON.parse(typeof body === 'string' ? body : Buffer.from(body).toString('ascii'));
|
|
158
142
|
const decryptedBody = node_utils_1.Security.decryptObject(bodyJSON, this.encryptionKey);
|
|
159
143
|
return JSON.parse(decryptedBody.content);
|
|
160
144
|
}
|
|
@@ -181,9 +165,11 @@ class CloudTaskConnector {
|
|
|
181
165
|
const [error, resp] = await js_utils_1.Promises.try(client.getTask({ name, responseView: 'FULL' }));
|
|
182
166
|
// This in most cases will mean success, given that the tasks get removed once they are done
|
|
183
167
|
if (error?.message.includes('The task no longer exists')) {
|
|
168
|
+
// Extract task name once
|
|
169
|
+
const taskName = name?.split('/').pop() || '';
|
|
184
170
|
return {
|
|
185
171
|
id: name,
|
|
186
|
-
name:
|
|
172
|
+
name: taskName,
|
|
187
173
|
output: error?.message,
|
|
188
174
|
attempts: 0,
|
|
189
175
|
status: 'COMPLETED',
|
|
@@ -194,29 +180,29 @@ class CloudTaskConnector {
|
|
|
194
180
|
};
|
|
195
181
|
}
|
|
196
182
|
const task = resp[0];
|
|
183
|
+
// Extract values once
|
|
184
|
+
const dispatchCount = task.dispatchCount ?? 0;
|
|
185
|
+
const responseCount = task.responseCount || 0;
|
|
197
186
|
const creation = Number(task.createTime?.seconds || 0) || 0;
|
|
198
187
|
const scheduled = Number(task.scheduleTime?.seconds || 0) || 0;
|
|
199
|
-
|
|
188
|
+
// Determine status with simplified logic
|
|
200
189
|
let status = 'RUNNING';
|
|
201
|
-
if (
|
|
202
|
-
(task.responseCount === 0 &&
|
|
203
|
-
(task.dispatchCount === 1 || task.dispatchCount === 0))) {
|
|
190
|
+
if (responseCount === 0 && (dispatchCount > 2 || dispatchCount <= 1)) {
|
|
204
191
|
status = 'FAILED';
|
|
205
192
|
}
|
|
206
|
-
else if (
|
|
207
|
-
task.responseCount > 0) {
|
|
193
|
+
else if (responseCount > 0) {
|
|
208
194
|
status = 'COMPLETED';
|
|
209
195
|
}
|
|
210
196
|
return {
|
|
211
197
|
id: task.name || '',
|
|
212
198
|
name: task.name?.split('/').pop() || '',
|
|
213
|
-
attempts:
|
|
199
|
+
attempts: dispatchCount,
|
|
214
200
|
output: task.lastAttempt?.responseStatus?.message || '',
|
|
215
201
|
status,
|
|
216
202
|
created: new Date(creation * 1000).toISOString(),
|
|
217
|
-
nextRun: new Date(scheduled * 1000).toISOString(),
|
|
218
|
-
nextRunMinutes: getScheduledInfo(scheduled).minutesUntil,
|
|
219
|
-
payload
|
|
203
|
+
nextRun: scheduled ? new Date(scheduled * 1000).toISOString() : null,
|
|
204
|
+
nextRunMinutes: scheduled ? getScheduledInfo(scheduled).minutesUntil : null,
|
|
205
|
+
payload: this.decryptBody(task.httpRequest?.body)
|
|
220
206
|
};
|
|
221
207
|
}
|
|
222
208
|
/**
|
|
@@ -241,14 +227,15 @@ class CloudTaskConnector {
|
|
|
241
227
|
});
|
|
242
228
|
const creation = Number(task.createTime?.seconds || 0) || 0;
|
|
243
229
|
const scheduled = Number(task.scheduleTime?.seconds || 0) || 0;
|
|
230
|
+
const taskName = task.name.split('/').pop() || '';
|
|
244
231
|
return {
|
|
245
232
|
id: task.name,
|
|
246
|
-
name:
|
|
233
|
+
name: taskName,
|
|
247
234
|
output: '',
|
|
248
235
|
attempts: 0,
|
|
249
236
|
status: 'QUEUED',
|
|
250
|
-
created: new Date(creation * 1000).toISOString(),
|
|
251
|
-
nextRun: new Date(scheduled * 1000).toISOString(),
|
|
237
|
+
created: creation ? new Date(creation * 1000).toISOString() : new Date().toISOString(),
|
|
238
|
+
nextRun: scheduled ? new Date(scheduled * 1000).toISOString() : null,
|
|
252
239
|
nextRunMinutes: null
|
|
253
240
|
};
|
|
254
241
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CloudTaskConnector.js","sourceRoot":"","sources":["../src/CloudTaskConnector.ts"],"names":[],"mappings":";;;;AAMA,gDAA0E;AAC1E,oDAA8C;AAM9C,MAAM,sBAAsB,GAAoB;IAC9C,UAAU,EAAE,CAAC;IACb,uBAAuB,EAAE,IAAI;IAC7B,oBAAoB,EAAE,GAAG;IACzB,mBAAmB,EAAE,IAAI;IACzB,uBAAuB,EAAE,IAAI;CAC9B,CAAA;AAED,SAAS,gBAAgB,CAAC,SAAiB;IAGzC,IAAI,SAAS,KAAK,CAAC,EAAE;QACnB,OAAO;YACL,YAAY,EAAE,CAAC;SAChB,CAAA;KACF;
|
|
1
|
+
{"version":3,"file":"CloudTaskConnector.js","sourceRoot":"","sources":["../src/CloudTaskConnector.ts"],"names":[],"mappings":"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"}
|