diff --git a/spec/runtime/manifest.spec.ts b/spec/runtime/manifest.spec.ts index 7534ba2ee..5660f369a 100644 --- a/spec/runtime/manifest.spec.ts +++ b/spec/runtime/manifest.spec.ts @@ -259,6 +259,7 @@ describe("initScheduleTrigger", () => { expect(st).to.deep.eq({ schedule: "every 30 minutes", timeZone: RESET_VALUE, + attemptDeadline: RESET_VALUE, retryConfig: { retryCount: RESET_VALUE, maxDoublings: RESET_VALUE, @@ -286,6 +287,7 @@ describe("initScheduleTrigger", () => { expect(st).to.deep.eq({ schedule: "every 30 minutes", timeZone: RESET_VALUE, + attemptDeadline: RESET_VALUE, retryConfig: { retryCount: RESET_VALUE, maxDoublings: RESET_VALUE, diff --git a/spec/v1/cloud-functions.spec.ts b/spec/v1/cloud-functions.spec.ts index d85afbe2f..c15240035 100644 --- a/spec/v1/cloud-functions.spec.ts +++ b/spec/v1/cloud-functions.spec.ts @@ -206,6 +206,7 @@ describe("makeCloudFunction", () => { platform: "gcfv1", scheduleTrigger: { ...schedule, + attemptDeadline: RESET_VALUE, retryConfig: { ...schedule.retryConfig, maxBackoffDuration: RESET_VALUE, diff --git a/spec/v1/providers/fixtures.ts b/spec/v1/providers/fixtures.ts index e047ba07f..12b3d9f67 100644 --- a/spec/v1/providers/fixtures.ts +++ b/spec/v1/providers/fixtures.ts @@ -47,4 +47,5 @@ export const MINIMAL_SCHEDULE_TRIGGER: ManifestEndpoint["scheduleTrigger"] = { minBackoffDuration: options.RESET_VALUE, maxDoublings: options.RESET_VALUE, }, + attemptDeadline: options.RESET_VALUE, }; diff --git a/spec/v1/providers/pubsub.spec.ts b/spec/v1/providers/pubsub.spec.ts index 0a7b89ad6..b56aa98be 100644 --- a/spec/v1/providers/pubsub.spec.ts +++ b/spec/v1/providers/pubsub.spec.ts @@ -215,7 +215,9 @@ describe("Pubsub Functions", () => { expect(result.__endpoint.scheduleTrigger).to.deep.equal({ ...MINIMAL_SCHEDULE_TRIGGER, schedule: "every 5 minutes", - retryConfig, + retryConfig: { + ...retryConfig, + }, }); expect(result.__endpoint.labels).to.be.empty; }); @@ -249,7 +251,9 @@ describe("Pubsub Functions", () => { expect(result.__endpoint.scheduleTrigger).to.deep.equal({ ...MINIMAL_SCHEDULE_TRIGGER, schedule: "every 5 minutes", - retryConfig, + retryConfig: { + ...retryConfig, + }, timeZone: "America/New_York", }); expect(result.__endpoint.labels).to.be.empty; @@ -341,7 +345,9 @@ describe("Pubsub Functions", () => { ...MINIMAL_SCHEDULE_TRIGGER, schedule: "every 5 minutes", timeZone: RESET_VALUE, - retryConfig, + retryConfig: { + ...retryConfig, + }, }); expect(result.__endpoint.region).to.deep.equal(["us-east1"]); expect(result.__endpoint.availableMemoryMb).to.deep.equal(256); @@ -382,7 +388,9 @@ describe("Pubsub Functions", () => { ...MINIMAL_SCHEDULE_TRIGGER, schedule: "every 5 minutes", timeZone: "America/New_York", - retryConfig, + retryConfig: { + ...retryConfig, + }, }); expect(result.__endpoint.region).to.deep.equal(["us-east1"]); expect(result.__endpoint.availableMemoryMb).to.deep.equal(256); diff --git a/spec/v2/providers/scheduler.spec.ts b/spec/v2/providers/scheduler.spec.ts index fcd03cf1f..5946e77cd 100644 --- a/spec/v2/providers/scheduler.spec.ts +++ b/spec/v2/providers/scheduler.spec.ts @@ -39,6 +39,7 @@ const MINIMAL_SCHEDULE_TRIGGER: ManifestEndpoint["scheduleTrigger"] = { maxBackoffSeconds: options.RESET_VALUE, maxDoublings: options.RESET_VALUE, }, + attemptDeadline: options.RESET_VALUE, }; describe("schedule", () => { @@ -59,6 +60,7 @@ describe("schedule", () => { minBackoffSeconds: 2, maxBackoffSeconds: 3, maxDoublings: 4, + attemptDeadline: "120s", memory: "128MiB", region: "us-central1", }; @@ -73,6 +75,7 @@ describe("schedule", () => { maxBackoffSeconds: 3, maxDoublings: 4, }, + attemptDeadline: "120s", opts: { ...options, memory: "128MiB", @@ -103,6 +106,20 @@ describe("schedule", () => { ]); }); + it("should create a schedule function with attemptDeadline", () => { + const schfn = schedule.onSchedule( + { + schedule: "* * * * *", + attemptDeadline: "320s", + }, + () => undefined + ); + + expect(schfn.__endpoint.scheduleTrigger?.attemptDeadline).to.equal( + "320s" + ); + }); + it("should create a schedule function given options", () => { const schfn = schedule.onSchedule( { @@ -113,6 +130,7 @@ describe("schedule", () => { minBackoffSeconds: 11, maxBackoffSeconds: 12, maxDoublings: 2, + attemptDeadline: "120s", region: "us-central1", labels: { key: "val" }, }, @@ -134,6 +152,7 @@ describe("schedule", () => { maxBackoffSeconds: 12, maxDoublings: 2, }, + attemptDeadline: "120s", }, }); expect(schfn.__requiredAPIs).to.deep.eq([ @@ -159,6 +178,7 @@ describe("schedule", () => { scheduleTrigger: { schedule: "* * * * *", timeZone: undefined, + attemptDeadline: undefined, retryConfig: { retryCount: undefined, maxRetrySeconds: undefined, diff --git a/src/runtime/manifest.ts b/src/runtime/manifest.ts index 4d52d5eaf..2744dac90 100644 --- a/src/runtime/manifest.ts +++ b/src/runtime/manifest.ts @@ -108,6 +108,7 @@ export interface ManifestEndpoint { minBackoffDuration?: string | Expression | ResetValue; maxBackoffDuration?: string | Expression | ResetValue; }; + attemptDeadline?: string | Expression | ResetValue; }; blockingTrigger?: { @@ -280,7 +281,7 @@ function initScheduleTrigger( for (const key of Object.keys(resetOptions)) { scheduleTrigger.retryConfig[key] = RESET_VALUE; } - scheduleTrigger = { ...scheduleTrigger, timeZone: RESET_VALUE }; + scheduleTrigger = { ...scheduleTrigger, timeZone: RESET_VALUE, attemptDeadline: RESET_VALUE }; } return scheduleTrigger; } diff --git a/src/v1/cloud-functions.ts b/src/v1/cloud-functions.ts index 0a86853f9..adcf5668b 100644 --- a/src/v1/cloud-functions.ts +++ b/src/v1/cloud-functions.ts @@ -485,7 +485,7 @@ export function makeCloudFunction({ "maxDoublings", "maxBackoffDuration", "maxRetryDuration", - "minBackoffDuration" + "minBackoffDuration", ); } else { endpoint.eventTrigger = { diff --git a/src/v1/function-configuration.ts b/src/v1/function-configuration.ts index 90aa391fc..b40b33a6c 100644 --- a/src/v1/function-configuration.ts +++ b/src/v1/function-configuration.ts @@ -110,6 +110,11 @@ export interface ScheduleRetryConfig { * @defaultValue 5 */ maxDoublings?: number | Expression | ResetValue; + + /** + * The deadline for each job attempt, specified as a duration string (e.g. "600s"). + */ + attemptDeadline?: string | Expression | ResetValue; } /** diff --git a/src/v2/providers/scheduler.ts b/src/v2/providers/scheduler.ts index 1f8f33c31..c214f4bb6 100644 --- a/src/v2/providers/scheduler.ts +++ b/src/v2/providers/scheduler.ts @@ -49,6 +49,7 @@ interface SeparatedOpts { maxBackoffSeconds?: number | Expression | ResetValue; maxDoublings?: number | Expression | ResetValue; }; + attemptDeadline?: string | Expression | ResetValue; opts: options.GlobalOptions; } @@ -60,6 +61,7 @@ export function getOpts(args: string | ScheduleOptions): SeparatedOpts { opts: {} as options.GlobalOptions, }; } + return { schedule: args.schedule, timeZone: args.timeZone, @@ -70,6 +72,7 @@ export function getOpts(args: string | ScheduleOptions): SeparatedOpts { maxBackoffSeconds: args.maxBackoffSeconds, maxDoublings: args.maxDoublings, }, + attemptDeadline: args.attemptDeadline, opts: args as options.GlobalOptions, }; } @@ -125,6 +128,12 @@ export interface ScheduleOptions extends options.GlobalOptions { /** The time between will double max doublings times. */ maxDoublings?: number | Expression | ResetValue; + + /** + * The deadline for each job attempt, specified as a duration string (e.g. "600s"). + * See: https://cloud.google.com/scheduler/docs/reference/rest/v1/projects.locations.jobs#Job + */ + attemptDeadline?: string | Expression | ResetValue; } /** @@ -197,6 +206,7 @@ export function onSchedule( }; copyIfPresent(ep.scheduleTrigger, separatedOpts, "timeZone"); + copyIfPresent(ep.scheduleTrigger, separatedOpts, "attemptDeadline"); copyIfPresent( ep.scheduleTrigger.retryConfig, separatedOpts.retryConfig, @@ -204,7 +214,7 @@ export function onSchedule( "maxRetrySeconds", "minBackoffSeconds", "maxBackoffSeconds", - "maxDoublings" + "maxDoublings", ); func.__endpoint = ep;