@spooled/sdk 1.0.33 → 1.0.35
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/dist/{index-QIsnz4Bc.d.cts → index-B96n0WUe.d.cts} +29 -3
- package/dist/{index-QIsnz4Bc.d.ts → index-B96n0WUe.d.ts} +29 -3
- package/dist/index.cjs +27 -20
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +27 -20
- package/dist/index.js.map +1 -1
- package/dist/worker/index.cjs +27 -19
- package/dist/worker/index.cjs.map +1 -1
- package/dist/worker/index.d.cts +1 -1
- package/dist/worker/index.d.ts +1 -1
- package/dist/worker/index.js +27 -19
- package/dist/worker/index.js.map +1 -1
- package/package.json +1 -1
- package/proto/spooled.proto +13 -0
|
@@ -107,11 +107,11 @@ declare const DEFAULT_CONFIG: {
|
|
|
107
107
|
successThreshold: number;
|
|
108
108
|
timeout: number;
|
|
109
109
|
};
|
|
110
|
-
readonly userAgent: "@spooled/sdk-nodejs/1.0.
|
|
110
|
+
readonly userAgent: "@spooled/sdk-nodejs/1.0.35";
|
|
111
111
|
readonly autoRefreshToken: true;
|
|
112
112
|
};
|
|
113
113
|
/** SDK version */
|
|
114
|
-
declare const SDK_VERSION = "1.0.
|
|
114
|
+
declare const SDK_VERSION = "1.0.35";
|
|
115
115
|
/** API version prefix */
|
|
116
116
|
declare const API_VERSION = "v1";
|
|
117
117
|
/**
|
|
@@ -559,7 +559,7 @@ interface Job {
|
|
|
559
559
|
parentJobId?: string;
|
|
560
560
|
completionWebhook?: string;
|
|
561
561
|
assignedWorkerId?: string;
|
|
562
|
-
leaseId?: string;
|
|
562
|
+
leaseId?: string | null;
|
|
563
563
|
leaseExpiresAt?: string;
|
|
564
564
|
idempotencyKey?: string;
|
|
565
565
|
updatedAt: string;
|
|
@@ -647,6 +647,13 @@ interface ClaimedJob {
|
|
|
647
647
|
maxRetries: number;
|
|
648
648
|
timeoutSeconds: number;
|
|
649
649
|
leaseExpiresAt?: string;
|
|
650
|
+
/**
|
|
651
|
+
* Lease fencing token for this claim. Echo it back on
|
|
652
|
+
* complete/fail/heartbeat so the operation applies only to the lease this
|
|
653
|
+
* worker actually holds (backend rejects stale leases with 409
|
|
654
|
+
* LEASE_EXPIRED). Omitted = legacy behavior.
|
|
655
|
+
*/
|
|
656
|
+
leaseId?: string | null;
|
|
650
657
|
}
|
|
651
658
|
/** Parameters for claiming jobs */
|
|
652
659
|
interface ClaimJobsParams {
|
|
@@ -669,6 +676,8 @@ interface CompleteJobParams {
|
|
|
669
676
|
workerId: string;
|
|
670
677
|
/** Optional result payload */
|
|
671
678
|
result?: JsonObject;
|
|
679
|
+
/** Lease fencing token from the claimed job (rejects stale leases when set) */
|
|
680
|
+
leaseId?: string;
|
|
672
681
|
}
|
|
673
682
|
/** Parameters for failing a job */
|
|
674
683
|
interface FailJobParams {
|
|
@@ -676,6 +685,8 @@ interface FailJobParams {
|
|
|
676
685
|
workerId: string;
|
|
677
686
|
/** Error message (1-2048 chars) */
|
|
678
687
|
error: string;
|
|
688
|
+
/** Lease fencing token from the claimed job (rejects stale leases when set) */
|
|
689
|
+
leaseId?: string;
|
|
679
690
|
}
|
|
680
691
|
/** Parameters for job heartbeat */
|
|
681
692
|
interface HeartbeatJobParams {
|
|
@@ -683,6 +694,8 @@ interface HeartbeatJobParams {
|
|
|
683
694
|
workerId: string;
|
|
684
695
|
/** Lease duration in seconds (5-3600) */
|
|
685
696
|
leaseDurationSecs: number;
|
|
697
|
+
/** Lease fencing token from the claimed job (rejects stale leases when set) */
|
|
698
|
+
leaseId?: string;
|
|
686
699
|
}
|
|
687
700
|
/** Response for priority boost */
|
|
688
701
|
interface BoostPriorityResponse {
|
|
@@ -2602,6 +2615,12 @@ interface GrpcJob {
|
|
|
2602
2615
|
leaseExpiresAt?: GrpcTimestamp | string | null;
|
|
2603
2616
|
assignedWorkerId?: string | null;
|
|
2604
2617
|
idempotencyKey?: string | null;
|
|
2618
|
+
/**
|
|
2619
|
+
* Lease fencing token (proto `lease_id`). Returned on dequeue; echo it back
|
|
2620
|
+
* in Complete/Fail/RenewLease so the operation applies only to the lease
|
|
2621
|
+
* this worker actually holds (empty = legacy worker_id fence).
|
|
2622
|
+
*/
|
|
2623
|
+
leaseId?: string | null;
|
|
2605
2624
|
}
|
|
2606
2625
|
/** Enqueue request */
|
|
2607
2626
|
interface GrpcEnqueueRequest {
|
|
@@ -2637,6 +2656,8 @@ interface GrpcCompleteRequest {
|
|
|
2637
2656
|
workerId: string;
|
|
2638
2657
|
/** Result as object (will be converted to google.protobuf.Struct) */
|
|
2639
2658
|
result?: Record<string, unknown>;
|
|
2659
|
+
/** Lease fencing token from the dequeued job (proto `lease_id`) */
|
|
2660
|
+
leaseId?: string;
|
|
2640
2661
|
}
|
|
2641
2662
|
/** Complete response */
|
|
2642
2663
|
interface GrpcCompleteResponse {
|
|
@@ -2648,6 +2669,8 @@ interface GrpcFailRequest {
|
|
|
2648
2669
|
workerId: string;
|
|
2649
2670
|
error: string;
|
|
2650
2671
|
retry?: boolean;
|
|
2672
|
+
/** Lease fencing token from the dequeued job (proto `lease_id`) */
|
|
2673
|
+
leaseId?: string;
|
|
2651
2674
|
}
|
|
2652
2675
|
/** Fail response */
|
|
2653
2676
|
interface GrpcFailResponse {
|
|
@@ -2660,6 +2683,8 @@ interface GrpcRenewLeaseRequest {
|
|
|
2660
2683
|
jobId: string;
|
|
2661
2684
|
workerId: string;
|
|
2662
2685
|
extensionSecs: number;
|
|
2686
|
+
/** Lease fencing token from the dequeued job (proto `lease_id`) */
|
|
2687
|
+
leaseId?: string;
|
|
2663
2688
|
}
|
|
2664
2689
|
/** Renew lease response */
|
|
2665
2690
|
interface GrpcRenewLeaseResponse {
|
|
@@ -3344,6 +3369,7 @@ interface WorkerEventData {
|
|
|
3344
3369
|
}
|
|
3345
3370
|
/** Active job tracking */
|
|
3346
3371
|
interface ActiveJob {
|
|
3372
|
+
readonly executionId: symbol;
|
|
3347
3373
|
job: ClaimedJob;
|
|
3348
3374
|
startedAt: Date;
|
|
3349
3375
|
heartbeatTimer?: ReturnType<typeof setInterval>;
|
|
@@ -107,11 +107,11 @@ declare const DEFAULT_CONFIG: {
|
|
|
107
107
|
successThreshold: number;
|
|
108
108
|
timeout: number;
|
|
109
109
|
};
|
|
110
|
-
readonly userAgent: "@spooled/sdk-nodejs/1.0.
|
|
110
|
+
readonly userAgent: "@spooled/sdk-nodejs/1.0.35";
|
|
111
111
|
readonly autoRefreshToken: true;
|
|
112
112
|
};
|
|
113
113
|
/** SDK version */
|
|
114
|
-
declare const SDK_VERSION = "1.0.
|
|
114
|
+
declare const SDK_VERSION = "1.0.35";
|
|
115
115
|
/** API version prefix */
|
|
116
116
|
declare const API_VERSION = "v1";
|
|
117
117
|
/**
|
|
@@ -559,7 +559,7 @@ interface Job {
|
|
|
559
559
|
parentJobId?: string;
|
|
560
560
|
completionWebhook?: string;
|
|
561
561
|
assignedWorkerId?: string;
|
|
562
|
-
leaseId?: string;
|
|
562
|
+
leaseId?: string | null;
|
|
563
563
|
leaseExpiresAt?: string;
|
|
564
564
|
idempotencyKey?: string;
|
|
565
565
|
updatedAt: string;
|
|
@@ -647,6 +647,13 @@ interface ClaimedJob {
|
|
|
647
647
|
maxRetries: number;
|
|
648
648
|
timeoutSeconds: number;
|
|
649
649
|
leaseExpiresAt?: string;
|
|
650
|
+
/**
|
|
651
|
+
* Lease fencing token for this claim. Echo it back on
|
|
652
|
+
* complete/fail/heartbeat so the operation applies only to the lease this
|
|
653
|
+
* worker actually holds (backend rejects stale leases with 409
|
|
654
|
+
* LEASE_EXPIRED). Omitted = legacy behavior.
|
|
655
|
+
*/
|
|
656
|
+
leaseId?: string | null;
|
|
650
657
|
}
|
|
651
658
|
/** Parameters for claiming jobs */
|
|
652
659
|
interface ClaimJobsParams {
|
|
@@ -669,6 +676,8 @@ interface CompleteJobParams {
|
|
|
669
676
|
workerId: string;
|
|
670
677
|
/** Optional result payload */
|
|
671
678
|
result?: JsonObject;
|
|
679
|
+
/** Lease fencing token from the claimed job (rejects stale leases when set) */
|
|
680
|
+
leaseId?: string;
|
|
672
681
|
}
|
|
673
682
|
/** Parameters for failing a job */
|
|
674
683
|
interface FailJobParams {
|
|
@@ -676,6 +685,8 @@ interface FailJobParams {
|
|
|
676
685
|
workerId: string;
|
|
677
686
|
/** Error message (1-2048 chars) */
|
|
678
687
|
error: string;
|
|
688
|
+
/** Lease fencing token from the claimed job (rejects stale leases when set) */
|
|
689
|
+
leaseId?: string;
|
|
679
690
|
}
|
|
680
691
|
/** Parameters for job heartbeat */
|
|
681
692
|
interface HeartbeatJobParams {
|
|
@@ -683,6 +694,8 @@ interface HeartbeatJobParams {
|
|
|
683
694
|
workerId: string;
|
|
684
695
|
/** Lease duration in seconds (5-3600) */
|
|
685
696
|
leaseDurationSecs: number;
|
|
697
|
+
/** Lease fencing token from the claimed job (rejects stale leases when set) */
|
|
698
|
+
leaseId?: string;
|
|
686
699
|
}
|
|
687
700
|
/** Response for priority boost */
|
|
688
701
|
interface BoostPriorityResponse {
|
|
@@ -2602,6 +2615,12 @@ interface GrpcJob {
|
|
|
2602
2615
|
leaseExpiresAt?: GrpcTimestamp | string | null;
|
|
2603
2616
|
assignedWorkerId?: string | null;
|
|
2604
2617
|
idempotencyKey?: string | null;
|
|
2618
|
+
/**
|
|
2619
|
+
* Lease fencing token (proto `lease_id`). Returned on dequeue; echo it back
|
|
2620
|
+
* in Complete/Fail/RenewLease so the operation applies only to the lease
|
|
2621
|
+
* this worker actually holds (empty = legacy worker_id fence).
|
|
2622
|
+
*/
|
|
2623
|
+
leaseId?: string | null;
|
|
2605
2624
|
}
|
|
2606
2625
|
/** Enqueue request */
|
|
2607
2626
|
interface GrpcEnqueueRequest {
|
|
@@ -2637,6 +2656,8 @@ interface GrpcCompleteRequest {
|
|
|
2637
2656
|
workerId: string;
|
|
2638
2657
|
/** Result as object (will be converted to google.protobuf.Struct) */
|
|
2639
2658
|
result?: Record<string, unknown>;
|
|
2659
|
+
/** Lease fencing token from the dequeued job (proto `lease_id`) */
|
|
2660
|
+
leaseId?: string;
|
|
2640
2661
|
}
|
|
2641
2662
|
/** Complete response */
|
|
2642
2663
|
interface GrpcCompleteResponse {
|
|
@@ -2648,6 +2669,8 @@ interface GrpcFailRequest {
|
|
|
2648
2669
|
workerId: string;
|
|
2649
2670
|
error: string;
|
|
2650
2671
|
retry?: boolean;
|
|
2672
|
+
/** Lease fencing token from the dequeued job (proto `lease_id`) */
|
|
2673
|
+
leaseId?: string;
|
|
2651
2674
|
}
|
|
2652
2675
|
/** Fail response */
|
|
2653
2676
|
interface GrpcFailResponse {
|
|
@@ -2660,6 +2683,8 @@ interface GrpcRenewLeaseRequest {
|
|
|
2660
2683
|
jobId: string;
|
|
2661
2684
|
workerId: string;
|
|
2662
2685
|
extensionSecs: number;
|
|
2686
|
+
/** Lease fencing token from the dequeued job (proto `lease_id`) */
|
|
2687
|
+
leaseId?: string;
|
|
2663
2688
|
}
|
|
2664
2689
|
/** Renew lease response */
|
|
2665
2690
|
interface GrpcRenewLeaseResponse {
|
|
@@ -3344,6 +3369,7 @@ interface WorkerEventData {
|
|
|
3344
3369
|
}
|
|
3345
3370
|
/** Active job tracking */
|
|
3346
3371
|
interface ActiveJob {
|
|
3372
|
+
readonly executionId: symbol;
|
|
3347
3373
|
job: ClaimedJob;
|
|
3348
3374
|
startedAt: Date;
|
|
3349
3375
|
heartbeatTimer?: ReturnType<typeof setInterval>;
|
package/dist/index.cjs
CHANGED
|
@@ -49,10 +49,10 @@ var DEFAULT_CONFIG = {
|
|
|
49
49
|
successThreshold: 3,
|
|
50
50
|
timeout: 3e4
|
|
51
51
|
},
|
|
52
|
-
userAgent: "@spooled/sdk-nodejs/1.0.
|
|
52
|
+
userAgent: "@spooled/sdk-nodejs/1.0.35",
|
|
53
53
|
autoRefreshToken: true
|
|
54
54
|
};
|
|
55
|
-
var SDK_VERSION = "1.0.
|
|
55
|
+
var SDK_VERSION = "1.0.35";
|
|
56
56
|
var API_VERSION = "v1";
|
|
57
57
|
var API_BASE_PATH = `/api/${API_VERSION}`;
|
|
58
58
|
function normalizeCredential(value) {
|
|
@@ -3288,7 +3288,7 @@ var SpooledWorker = class {
|
|
|
3288
3288
|
...DEFAULT_OPTIONS,
|
|
3289
3289
|
hostname: os.hostname(),
|
|
3290
3290
|
workerType: "nodejs",
|
|
3291
|
-
version:
|
|
3291
|
+
version: SDK_VERSION,
|
|
3292
3292
|
metadata: {},
|
|
3293
3293
|
...options
|
|
3294
3294
|
};
|
|
@@ -3395,11 +3395,11 @@ var SpooledWorker = class {
|
|
|
3395
3395
|
this.waitForActiveJobs(),
|
|
3396
3396
|
this.sleep(this.options.shutdownTimeout)
|
|
3397
3397
|
]);
|
|
3398
|
-
const remaining = Array.from(this.activeJobs.
|
|
3399
|
-
for (const
|
|
3400
|
-
this.debug(`Force-failing job ${
|
|
3398
|
+
const remaining = Array.from(this.activeJobs.values());
|
|
3399
|
+
for (const active of remaining) {
|
|
3400
|
+
this.debug(`Force-failing job ${active.job.id} due to shutdown timeout`);
|
|
3401
3401
|
await this.failJob(active.job, "Worker shutdown timeout");
|
|
3402
|
-
this.cleanupJob(
|
|
3402
|
+
this.cleanupJob(active);
|
|
3403
3403
|
}
|
|
3404
3404
|
}
|
|
3405
3405
|
if (this.workerId) {
|
|
@@ -3482,14 +3482,15 @@ var SpooledWorker = class {
|
|
|
3482
3482
|
this.emit("job:claimed", { jobId: job.id, queueName: job.queueName });
|
|
3483
3483
|
const abortController = new AbortController();
|
|
3484
3484
|
const activeJob = {
|
|
3485
|
+
executionId: Symbol(job.id),
|
|
3485
3486
|
job,
|
|
3486
3487
|
startedAt: /* @__PURE__ */ new Date(),
|
|
3487
3488
|
abortController
|
|
3488
3489
|
};
|
|
3489
|
-
this.activeJobs.set(
|
|
3490
|
+
this.activeJobs.set(activeJob.executionId, activeJob);
|
|
3490
3491
|
const heartbeatInterval = this.options.leaseDuration * this.options.heartbeatFraction * 1e3;
|
|
3491
3492
|
activeJob.heartbeatTimer = setInterval(() => {
|
|
3492
|
-
this.sendJobHeartbeat(
|
|
3493
|
+
this.sendJobHeartbeat(activeJob);
|
|
3493
3494
|
}, heartbeatInterval);
|
|
3494
3495
|
this.executeHandler(activeJob);
|
|
3495
3496
|
}
|
|
@@ -3525,7 +3526,7 @@ var SpooledWorker = class {
|
|
|
3525
3526
|
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
3526
3527
|
await this.failJob(job, errorMessage);
|
|
3527
3528
|
} finally {
|
|
3528
|
-
this.cleanupJob(
|
|
3529
|
+
this.cleanupJob(activeJob);
|
|
3529
3530
|
}
|
|
3530
3531
|
}
|
|
3531
3532
|
async completeJob(job, result) {
|
|
@@ -3533,7 +3534,8 @@ var SpooledWorker = class {
|
|
|
3533
3534
|
try {
|
|
3534
3535
|
await this.client.jobs.complete(job.id, {
|
|
3535
3536
|
workerId: this.workerId,
|
|
3536
|
-
result
|
|
3537
|
+
result,
|
|
3538
|
+
...job.leaseId != null && { leaseId: job.leaseId }
|
|
3537
3539
|
});
|
|
3538
3540
|
this.emit("job:completed", {
|
|
3539
3541
|
jobId: job.id,
|
|
@@ -3550,7 +3552,8 @@ var SpooledWorker = class {
|
|
|
3550
3552
|
try {
|
|
3551
3553
|
await this.client.jobs.fail(job.id, {
|
|
3552
3554
|
workerId: this.workerId,
|
|
3553
|
-
error: errorMessage
|
|
3555
|
+
error: errorMessage,
|
|
3556
|
+
...job.leaseId != null && { leaseId: job.leaseId }
|
|
3554
3557
|
});
|
|
3555
3558
|
this.emit("job:failed", {
|
|
3556
3559
|
jobId: job.id,
|
|
@@ -3562,22 +3565,26 @@ var SpooledWorker = class {
|
|
|
3562
3565
|
this.debug(`Failed to fail job ${job.id}`, error);
|
|
3563
3566
|
}
|
|
3564
3567
|
}
|
|
3565
|
-
cleanupJob(
|
|
3566
|
-
|
|
3567
|
-
if (activeJob?.heartbeatTimer) {
|
|
3568
|
+
cleanupJob(activeJob) {
|
|
3569
|
+
if (activeJob.heartbeatTimer) {
|
|
3568
3570
|
clearInterval(activeJob.heartbeatTimer);
|
|
3571
|
+
activeJob.heartbeatTimer = void 0;
|
|
3572
|
+
}
|
|
3573
|
+
if (this.activeJobs.get(activeJob.executionId) === activeJob) {
|
|
3574
|
+
this.activeJobs.delete(activeJob.executionId);
|
|
3569
3575
|
}
|
|
3570
|
-
this.activeJobs.delete(jobId);
|
|
3571
3576
|
}
|
|
3572
|
-
async sendJobHeartbeat(
|
|
3577
|
+
async sendJobHeartbeat(activeJob) {
|
|
3573
3578
|
if (!this.workerId) return;
|
|
3579
|
+
const { job } = activeJob;
|
|
3574
3580
|
try {
|
|
3575
|
-
await this.client.jobs.heartbeat(
|
|
3581
|
+
await this.client.jobs.heartbeat(job.id, {
|
|
3576
3582
|
workerId: this.workerId,
|
|
3577
|
-
leaseDurationSecs: this.options.leaseDuration
|
|
3583
|
+
leaseDurationSecs: this.options.leaseDuration,
|
|
3584
|
+
...job.leaseId != null && { leaseId: job.leaseId }
|
|
3578
3585
|
});
|
|
3579
3586
|
} catch (error) {
|
|
3580
|
-
this.debug(`Job heartbeat failed for ${
|
|
3587
|
+
this.debug(`Job heartbeat failed for ${job.id}`, error);
|
|
3581
3588
|
}
|
|
3582
3589
|
}
|
|
3583
3590
|
async sendWorkerHeartbeat() {
|