@goatlab/tasks-adapter-gcp 0.3.4 → 0.4.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.
@@ -1,20 +1,129 @@
1
1
  /// <reference types="node" />
2
2
  import { Primitive } from '@goatlab/js-utils';
3
- import type { TaskConnector, TaskStatus } from '@goatlab/tasks-core';
3
+ import type { TaskConnector, TaskStatus, TenantCredentials } from '@goatlab/tasks-core';
4
4
  import type { BackoffSettings } from 'google-gax/build/src/gax';
5
+ import { GCPServiceAccount } from './CloudTaskConnector.types.js';
5
6
  export type ITask = any;
6
7
  export type { BackoffSettings };
8
+ /**
9
+ * Configuration for CloudTaskConnector
10
+ */
11
+ export interface CloudTaskConnectorConfig {
12
+ /**
13
+ * GCP service account credentials for authentication.
14
+ */
15
+ gcpServiceAccount?: GCPServiceAccount;
16
+ /**
17
+ * GCP region/location for Cloud Tasks queues.
18
+ * Default: 'europe-west1'
19
+ */
20
+ location?: string;
21
+ /**
22
+ * Encryption key for task body encryption.
23
+ */
24
+ encryptionKey?: string;
25
+ /**
26
+ * GCP project ID.
27
+ */
28
+ gcpProject: string;
29
+ /**
30
+ * Tenant ID for multi-tenant isolation.
31
+ * When set, this tenant ID is used as a prefix for task names.
32
+ *
33
+ * Task naming pattern: {tenantId}-{taskName}
34
+ * Example: "acme-corp-my-task" instead of "my-task"
35
+ *
36
+ * This ensures each tenant's tasks are uniquely identified,
37
+ * providing isolation at the task level while sharing the same queue.
38
+ */
39
+ tenantId?: string;
40
+ /**
41
+ * Enable in-memory payload caching for testing.
42
+ * GCP Cloud Tasks removes completed tasks immediately, which means
43
+ * getStatus() cannot retrieve the payload after completion.
44
+ *
45
+ * When enabled, payloads are cached in memory when queueing
46
+ * and returned from getStatus() even after the task is removed.
47
+ *
48
+ * WARNING: Only enable for testing. In production, this will cause
49
+ * memory leaks as payloads accumulate.
50
+ *
51
+ * Default: false
52
+ */
53
+ enablePayloadCache?: boolean;
54
+ }
7
55
  export declare class CloudTaskConnector implements TaskConnector<object> {
8
56
  private gcpServiceAccount;
9
57
  private location;
10
58
  private encryptionKey;
11
59
  private gcpProject;
12
- constructor({ gcpServiceAccount, location, encryptionKey, gcpProject }: {
13
- gcpServiceAccount?: any;
14
- location?: string;
15
- encryptionKey?: string;
16
- gcpProject: string;
17
- });
60
+ private readonly _tenantId?;
61
+ private readonly config;
62
+ private readonly enablePayloadCache;
63
+ /**
64
+ * Cache for task payloads (only used when enablePayloadCache is true).
65
+ * GCP Cloud Tasks removes completed tasks immediately, so we cache the payload
66
+ * to return it when getStatus is called after completion.
67
+ * Key: task name (full path), Value: { payload, createdAt }
68
+ */
69
+ private static payloadCache;
70
+ /**
71
+ * How long to keep payloads in cache (1 hour)
72
+ */
73
+ private static readonly CACHE_TTL_MS;
74
+ /**
75
+ * The tenant ID this connector is scoped to.
76
+ * When set, task names are prefixed with this tenant ID.
77
+ */
78
+ get tenantId(): string | undefined;
79
+ constructor(config: CloudTaskConnectorConfig);
80
+ /**
81
+ * Cleans up expired entries from the payload cache.
82
+ */
83
+ private cleanupCache;
84
+ /**
85
+ * Caches a task's payload for later retrieval.
86
+ * Only caches if enablePayloadCache is true.
87
+ */
88
+ private cachePayload;
89
+ /**
90
+ * Gets a cached payload if available.
91
+ * Only returns cached data if enablePayloadCache is true.
92
+ */
93
+ private getCachedPayload;
94
+ /**
95
+ * Creates a new CloudTaskConnector instance scoped to a specific tenant.
96
+ * Uses tenant ID as a prefix for queue names for isolation.
97
+ *
98
+ * @param tenantId - The tenant identifier for isolation (used as queue name prefix)
99
+ * @param credentials - Optional GCP credentials for the tenant (uses parent's if not provided)
100
+ * @returns A new CloudTaskConnector instance scoped to the tenant
101
+ *
102
+ * @example
103
+ * ```typescript
104
+ * const baseConnector = new CloudTaskConnector({ gcpProject: 'my-project' })
105
+ *
106
+ * // Create tenant-scoped connector
107
+ * const tenantConnector = baseConnector.forTenant('acme-corp')
108
+ * // Queue names: acme-corp-default, acme-corp-email-queue, etc.
109
+ * ```
110
+ */
111
+ forTenant(tenantId: string, _credentials?: TenantCredentials): CloudTaskConnector;
112
+ /**
113
+ * Sanitizes a string for use in GCP Cloud Tasks names.
114
+ * GCP names only allow letters, numbers, and hyphens.
115
+ * @param value - The value to sanitize
116
+ * @returns Sanitized value safe for GCP names
117
+ */
118
+ private sanitizeForGcp;
119
+ /**
120
+ * Gets the task name with tenant prefix applied if tenant is set.
121
+ * Task-level isolation: all tenants share the same queue, but task names are prefixed.
122
+ * This avoids the overhead of creating separate queues per tenant.
123
+ * @param taskName - The base task name
124
+ * @returns The full task name with tenant prefix if applicable
125
+ */
126
+ private getTaskName;
18
127
  private getCloudTasksClient;
19
128
  /**
20
129
  * Adds a task to the Cloud Tasks queue.
@@ -25,7 +134,7 @@ export declare class CloudTaskConnector implements TaskConnector<object> {
25
134
  queueName: string;
26
135
  backoffSettings: any;
27
136
  baseUrl?: string;
28
- }): Promise<import("@google-cloud/tasks/build/protos/protos").google.cloud.tasks.v2.ITask>;
137
+ }): Promise<import("@google-cloud/tasks/build/protos/protos.js").google.cloud.tasks.v2.ITask>;
29
138
  /**
30
139
  * Lists all failed tasks in the specified queue.
31
140
  * It filters tasks that have been dispatched more than twice,
@@ -34,7 +143,7 @@ export declare class CloudTaskConnector implements TaskConnector<object> {
34
143
  * @param queueName - Name of the queue to list failed tasks from.
35
144
  * @returns An array of failed tasks.
36
145
  */
37
- listFailedTasks(queueName?: string): Promise<import("@google-cloud/tasks/build/protos/protos").google.cloud.tasks.v2.ITask[]>;
146
+ listFailedTasks(queueName?: string): Promise<import("@google-cloud/tasks/build/protos/protos.js").google.cloud.tasks.v2.ITask[]>;
38
147
  /**
39
148
  * Decrypts the body of a task.
40
149
  * This service encrypts the body of the task before sending it,
@@ -28,11 +28,138 @@ class CloudTaskConnector {
28
28
  location;
29
29
  encryptionKey;
30
30
  gcpProject;
31
- constructor({ gcpServiceAccount, location, encryptionKey, gcpProject }) {
32
- this.gcpServiceAccount = gcpServiceAccount || '';
33
- this.location = location || 'europe-west1';
34
- this.encryptionKey = encryptionKey || '';
35
- this.gcpProject = gcpProject || '';
31
+ _tenantId;
32
+ config;
33
+ enablePayloadCache;
34
+ /**
35
+ * Cache for task payloads (only used when enablePayloadCache is true).
36
+ * GCP Cloud Tasks removes completed tasks immediately, so we cache the payload
37
+ * to return it when getStatus is called after completion.
38
+ * Key: task name (full path), Value: { payload, createdAt }
39
+ */
40
+ static payloadCache = new Map();
41
+ /**
42
+ * How long to keep payloads in cache (1 hour)
43
+ */
44
+ static CACHE_TTL_MS = 60 * 60 * 1000;
45
+ /**
46
+ * The tenant ID this connector is scoped to.
47
+ * When set, task names are prefixed with this tenant ID.
48
+ */
49
+ get tenantId() {
50
+ return this._tenantId;
51
+ }
52
+ constructor(config) {
53
+ this.config = config;
54
+ this.gcpServiceAccount = (config.gcpServiceAccount ||
55
+ '');
56
+ this.location = config.location || 'europe-west1';
57
+ this.encryptionKey = config.encryptionKey || '';
58
+ this.gcpProject = config.gcpProject || '';
59
+ this._tenantId = config.tenantId;
60
+ this.enablePayloadCache = config.enablePayloadCache ?? false;
61
+ // Periodically clean up old cache entries (only if caching is enabled)
62
+ if (this.enablePayloadCache) {
63
+ this.cleanupCache();
64
+ }
65
+ }
66
+ /**
67
+ * Cleans up expired entries from the payload cache.
68
+ */
69
+ cleanupCache() {
70
+ if (!this.enablePayloadCache) {
71
+ return;
72
+ }
73
+ const now = Date.now();
74
+ for (const [key, value] of CloudTaskConnector.payloadCache) {
75
+ if (now - value.createdAt > CloudTaskConnector.CACHE_TTL_MS) {
76
+ CloudTaskConnector.payloadCache.delete(key);
77
+ }
78
+ }
79
+ }
80
+ /**
81
+ * Caches a task's payload for later retrieval.
82
+ * Only caches if enablePayloadCache is true.
83
+ */
84
+ cachePayload(taskName, payload) {
85
+ if (!this.enablePayloadCache) {
86
+ return;
87
+ }
88
+ CloudTaskConnector.payloadCache.set(taskName, {
89
+ payload,
90
+ createdAt: Date.now()
91
+ });
92
+ }
93
+ /**
94
+ * Gets a cached payload if available.
95
+ * Only returns cached data if enablePayloadCache is true.
96
+ */
97
+ getCachedPayload(taskName) {
98
+ if (!this.enablePayloadCache) {
99
+ return undefined;
100
+ }
101
+ const cached = CloudTaskConnector.payloadCache.get(taskName);
102
+ if (cached) {
103
+ // Check if expired
104
+ if (Date.now() - cached.createdAt > CloudTaskConnector.CACHE_TTL_MS) {
105
+ CloudTaskConnector.payloadCache.delete(taskName);
106
+ return undefined;
107
+ }
108
+ return cached.payload;
109
+ }
110
+ return undefined;
111
+ }
112
+ /**
113
+ * Creates a new CloudTaskConnector instance scoped to a specific tenant.
114
+ * Uses tenant ID as a prefix for queue names for isolation.
115
+ *
116
+ * @param tenantId - The tenant identifier for isolation (used as queue name prefix)
117
+ * @param credentials - Optional GCP credentials for the tenant (uses parent's if not provided)
118
+ * @returns A new CloudTaskConnector instance scoped to the tenant
119
+ *
120
+ * @example
121
+ * ```typescript
122
+ * const baseConnector = new CloudTaskConnector({ gcpProject: 'my-project' })
123
+ *
124
+ * // Create tenant-scoped connector
125
+ * const tenantConnector = baseConnector.forTenant('acme-corp')
126
+ * // Queue names: acme-corp-default, acme-corp-email-queue, etc.
127
+ * ```
128
+ */
129
+ forTenant(tenantId, _credentials) {
130
+ return new CloudTaskConnector({
131
+ ...this.config,
132
+ tenantId
133
+ });
134
+ }
135
+ /**
136
+ * Sanitizes a string for use in GCP Cloud Tasks names.
137
+ * GCP names only allow letters, numbers, and hyphens.
138
+ * @param value - The value to sanitize
139
+ * @returns Sanitized value safe for GCP names
140
+ */
141
+ sanitizeForGcp(value) {
142
+ // Replace underscores and other invalid chars with hyphens
143
+ // Remove any consecutive hyphens and trim hyphens from ends
144
+ return value
145
+ .replace(/[^a-zA-Z0-9-]/g, '-')
146
+ .replace(/-+/g, '-')
147
+ .replace(/^-|-$/g, '');
148
+ }
149
+ /**
150
+ * Gets the task name with tenant prefix applied if tenant is set.
151
+ * Task-level isolation: all tenants share the same queue, but task names are prefixed.
152
+ * This avoids the overhead of creating separate queues per tenant.
153
+ * @param taskName - The base task name
154
+ * @returns The full task name with tenant prefix if applicable
155
+ */
156
+ getTaskName(taskName) {
157
+ const sanitizedTask = this.sanitizeForGcp(taskName);
158
+ if (this._tenantId) {
159
+ const sanitizedTenant = this.sanitizeForGcp(this._tenantId);
160
+ return `${sanitizedTenant}-${sanitizedTask}`;
161
+ }
162
+ return sanitizedTask;
36
163
  }
37
164
  async getCloudTasksClient() {
38
165
  const cloudTasks = await Promise.resolve().then(() => require('@google-cloud/tasks'));
@@ -54,6 +181,7 @@ class CloudTaskConnector {
54
181
  const parsedURL = new URL(url, baseUrl);
55
182
  (0, js_utils_1.assert)(parsedURL, 'Task URL is invalid');
56
183
  const client = await this.getCloudTasksClient();
184
+ // Use queue name directly - tenant isolation is at task name level, not queue level
57
185
  const parent = client.queuePath(this.gcpProject, this.location, queueName);
58
186
  // Build the task object in one go to avoid multiple spreads
59
187
  const finalTask = {
@@ -116,6 +244,7 @@ class CloudTaskConnector {
116
244
  */
117
245
  async listFailedTasks(queueName = 'default') {
118
246
  const client = await this.getCloudTasksClient();
247
+ // Use queue name directly - tenant isolation is at task name level
119
248
  const parent = client.queuePath(this.gcpProject, this.location, queueName);
120
249
  // We have to be careful with the response, as it can be large.
121
250
  const [tasks] = await client.listTasks({ parent, responseView: 'FULL' });
@@ -167,6 +296,8 @@ class CloudTaskConnector {
167
296
  if (error?.message.includes('The task no longer exists')) {
168
297
  // Extract task name once
169
298
  const taskName = name?.split('/').pop() || '';
299
+ // Use cached payload if available (GCP removes completed tasks immediately)
300
+ const cachedPayload = this.getCachedPayload(name) || {};
170
301
  return {
171
302
  id: name,
172
303
  name: taskName,
@@ -176,7 +307,7 @@ class CloudTaskConnector {
176
307
  created: new Date().toISOString(),
177
308
  nextRun: null,
178
309
  nextRunMinutes: null,
179
- payload: {}
310
+ payload: cachedPayload
180
311
  };
181
312
  }
182
313
  const task = resp[0];
@@ -216,9 +347,13 @@ class CloudTaskConnector {
216
347
  * @param params.taskBody - Body of the task.
217
348
  */
218
349
  async queue(params) {
350
+ // Apply tenant prefix to task name for multi-tenant isolation
351
+ // All tenants share the same queue, but task names are prefixed
352
+ const baseTaskName = `${params.uniqueTaskName}-${js_utils_1.Ids.nanoId(5)}`;
353
+ const taskName = this.getTaskName(baseTaskName);
219
354
  const task = await this.addTask({
220
355
  task: {
221
- name: `${params.uniqueTaskName}_${js_utils_1.Ids.nanoId(5)}`,
356
+ name: taskName,
222
357
  httpRequest: {
223
358
  url: params.postUrl,
224
359
  body: JSON.stringify(params.taskBody)
@@ -227,12 +362,15 @@ class CloudTaskConnector {
227
362
  queueName: params.queueName || 'default',
228
363
  backoffSettings: defaultBackoffSettings
229
364
  });
365
+ // Cache the payload so we can return it even after GCP removes the completed task
366
+ if (task.name) {
367
+ this.cachePayload(task.name, params.taskBody);
368
+ }
230
369
  const creation = Number(task.createTime?.seconds || 0) || 0;
231
370
  const scheduled = Number(task.scheduleTime?.seconds || 0) || 0;
232
- const taskName = task.name.split('/').pop() || '';
233
371
  return {
234
372
  id: task.name,
235
- name: taskName,
373
+ name: params.taskName,
236
374
  output: '',
237
375
  attempts: 0,
238
376
  status: 'QUEUED',
@@ -1 +1 @@
1
- {"version":3,"file":"CloudTaskConnector.js","sourceRoot":"","sources":["../src/CloudTaskConnector.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"CloudTaskConnector.js","sourceRoot":"","sources":["../src/CloudTaskConnector.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,49 @@
1
+ /**
2
+ * MockCloudTaskConnector - In-memory mock for testing
3
+ *
4
+ * This connector simulates GCP Cloud Tasks behavior locally for testing purposes.
5
+ * It stores tasks in memory and executes them via a simulated worker,
6
+ * allowing us to run the same test suite as BullMQ and Hatchet adapters.
7
+ */
8
+ import type { ShouldQueue, TaskConnector, TaskStatus } from '@goatlab/tasks-core';
9
+ export declare class MockCloudTaskConnector implements TaskConnector<object> {
10
+ private tasks;
11
+ private taskHandlers;
12
+ private isProcessing;
13
+ private processInterval;
14
+ /**
15
+ * Registers task handlers (similar to BullMQ/Hatchet startWorker).
16
+ * This allows the mock to execute tasks when they are queued.
17
+ */
18
+ startWorker({ tasks }: {
19
+ workerName?: string;
20
+ tasks: ShouldQueue[];
21
+ }): Promise<() => Promise<void>>;
22
+ /**
23
+ * Processes queued tasks by executing their handlers.
24
+ * Simulates GCP Cloud Tasks calling HTTP endpoints.
25
+ */
26
+ private processTasks;
27
+ /**
28
+ * Gets the status of a task by its ID.
29
+ */
30
+ getStatus(id: string): Promise<TaskStatus>;
31
+ /**
32
+ * Queues a task to be run.
33
+ */
34
+ queue(params: {
35
+ uniqueTaskName: string;
36
+ taskName: string;
37
+ postUrl: string;
38
+ taskBody: object;
39
+ handle: () => Promise<any>;
40
+ }): Promise<Omit<TaskStatus, 'payload'>>;
41
+ /**
42
+ * Clears all stored tasks.
43
+ */
44
+ clear(): void;
45
+ /**
46
+ * Closes the connector and stops processing.
47
+ */
48
+ close(): Promise<void>;
49
+ }
@@ -0,0 +1,146 @@
1
+ "use strict";
2
+ /**
3
+ * MockCloudTaskConnector - In-memory mock for testing
4
+ *
5
+ * This connector simulates GCP Cloud Tasks behavior locally for testing purposes.
6
+ * It stores tasks in memory and executes them via a simulated worker,
7
+ * allowing us to run the same test suite as BullMQ and Hatchet adapters.
8
+ */
9
+ Object.defineProperty(exports, "__esModule", { value: true });
10
+ exports.MockCloudTaskConnector = void 0;
11
+ const js_utils_1 = require("@goatlab/js-utils");
12
+ class MockCloudTaskConnector {
13
+ tasks = new Map();
14
+ taskHandlers = new Map();
15
+ isProcessing = false;
16
+ processInterval = null;
17
+ /**
18
+ * Registers task handlers (similar to BullMQ/Hatchet startWorker).
19
+ * This allows the mock to execute tasks when they are queued.
20
+ */
21
+ async startWorker({ tasks }) {
22
+ for (const task of tasks) {
23
+ this.taskHandlers.set(task.taskName, task);
24
+ }
25
+ // Start processing tasks
26
+ this.isProcessing = true;
27
+ this.processInterval = setInterval(() => this.processTasks(), 50);
28
+ return async () => {
29
+ this.isProcessing = false;
30
+ if (this.processInterval) {
31
+ clearInterval(this.processInterval);
32
+ this.processInterval = null;
33
+ }
34
+ };
35
+ }
36
+ /**
37
+ * Processes queued tasks by executing their handlers.
38
+ * Simulates GCP Cloud Tasks calling HTTP endpoints.
39
+ */
40
+ async processTasks() {
41
+ if (!this.isProcessing) {
42
+ return;
43
+ }
44
+ for (const [_id, task] of this.tasks.entries()) {
45
+ if (task.status === 'QUEUED') {
46
+ // Mark as running
47
+ task.status = 'RUNNING';
48
+ task.attempts++;
49
+ const handler = this.taskHandlers.get(task.name);
50
+ if (handler) {
51
+ try {
52
+ const result = await handler.handle(task.payload);
53
+ task.status = 'COMPLETED';
54
+ task.output = result ? JSON.stringify(result) : '';
55
+ }
56
+ catch (error) {
57
+ task.status = 'FAILED';
58
+ task.output = error?.message || 'Unknown error';
59
+ }
60
+ }
61
+ else {
62
+ // No handler registered - mark as completed (simulates successful HTTP call)
63
+ task.status = 'COMPLETED';
64
+ }
65
+ }
66
+ }
67
+ }
68
+ /**
69
+ * Gets the status of a task by its ID.
70
+ */
71
+ async getStatus(id) {
72
+ const task = this.tasks.get(id);
73
+ if (!task) {
74
+ return {
75
+ id,
76
+ name: '',
77
+ status: 'COMPLETED',
78
+ output: 'Task not found',
79
+ attempts: 0,
80
+ created: new Date().toISOString(),
81
+ nextRun: null,
82
+ nextRunMinutes: null,
83
+ payload: {}
84
+ };
85
+ }
86
+ return {
87
+ id: task.id,
88
+ name: task.name,
89
+ status: task.status,
90
+ output: task.output,
91
+ attempts: task.attempts,
92
+ created: task.created,
93
+ nextRun: null,
94
+ nextRunMinutes: null,
95
+ payload: task.payload
96
+ };
97
+ }
98
+ /**
99
+ * Queues a task to be run.
100
+ */
101
+ async queue(params) {
102
+ const id = `mock-task-${params.uniqueTaskName}_${js_utils_1.Ids.nanoId(5)}`;
103
+ const now = new Date().toISOString();
104
+ const storedTask = {
105
+ id,
106
+ name: params.taskName,
107
+ payload: params.taskBody,
108
+ status: 'QUEUED',
109
+ attempts: 0,
110
+ created: now,
111
+ output: '',
112
+ handle: params.handle
113
+ };
114
+ this.tasks.set(id, storedTask);
115
+ return {
116
+ id,
117
+ name: params.taskName,
118
+ output: '',
119
+ attempts: 0,
120
+ status: 'QUEUED',
121
+ created: now,
122
+ nextRun: null,
123
+ nextRunMinutes: null
124
+ };
125
+ }
126
+ /**
127
+ * Clears all stored tasks.
128
+ */
129
+ clear() {
130
+ this.tasks.clear();
131
+ }
132
+ /**
133
+ * Closes the connector and stops processing.
134
+ */
135
+ async close() {
136
+ this.isProcessing = false;
137
+ if (this.processInterval) {
138
+ clearInterval(this.processInterval);
139
+ this.processInterval = null;
140
+ }
141
+ this.tasks.clear();
142
+ this.taskHandlers.clear();
143
+ }
144
+ }
145
+ exports.MockCloudTaskConnector = MockCloudTaskConnector;
146
+ //# sourceMappingURL=MockCloudTaskConnector.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MockCloudTaskConnector.js","sourceRoot":"","sources":["../src/MockCloudTaskConnector.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,17 @@
1
+ /**
2
+ * GCP Cloud Tasks Benchmark Script
3
+ *
4
+ * Run with: npx tsx src/benchmark.ts [mode]
5
+ *
6
+ * Modes:
7
+ * (default) - Run queue throughput benchmark
8
+ * payload - Compare different payload sizes
9
+ * batch - Compare different batch sizes
10
+ *
11
+ * Requires FIREBASE_SERVICE_ACCOUNT environment variable.
12
+ *
13
+ * Note: GCP Cloud Tasks is HTTP callback based, so we can only measure
14
+ * queue throughput (enqueue rate). E2E and latency tests would require
15
+ * a real HTTP endpoint to receive callbacks.
16
+ */
17
+ import 'dotenv/config';