From 4df3de2b648c69bd5ee5229c88cf1acb73399cec Mon Sep 17 00:00:00 2001 From: Pedro Leal Date: Wed, 21 Feb 2024 16:36:15 +0000 Subject: [PATCH 01/17] Added builders for consumer and queue POST bodies --- .../cli/commands/consumer/worker/add.ts | 38 ++++++---- .../src/queues/cli/commands/create.ts | 34 +++++++-- packages/wrangler/src/queues/client.ts | 70 ++----------------- 3 files changed, 58 insertions(+), 84 deletions(-) diff --git a/packages/wrangler/src/queues/cli/commands/consumer/worker/add.ts b/packages/wrangler/src/queues/cli/commands/consumer/worker/add.ts index e638d9a802d3..9e084d81439d 100644 --- a/packages/wrangler/src/queues/cli/commands/consumer/worker/add.ts +++ b/packages/wrangler/src/queues/cli/commands/consumer/worker/add.ts @@ -1,11 +1,8 @@ -import { readConfig } from "../../../../../config"; -import { logger } from "../../../../../logger"; -import { postConsumer } from "../../../../client"; -import type { - CommonYargsArgv, - StrictYargsOptionsToInterface, -} from "../../../../../yargs-types"; -import type { PostConsumerBody } from "../../../../client"; +import { readConfig } from "../../../../config"; +import { logger } from "../../../../logger"; +import type { PostConsumerBody } from "../../../client"; +import { postConsumer } from "../../../client"; +import type { CommonYargsArgv, StrictYargsOptionsToInterface } from "../../../../yargs-types"; export function options(yargs: CommonYargsArgv) { return yargs @@ -42,15 +39,21 @@ export function options(yargs: CommonYargsArgv) { describe: "The maximum number of concurrent consumer Worker invocations. Must be a positive integer", }, + "retry-delay": { + type: "number", + describe: + "TBD", + }, + "no-retry-delay": { + type: "boolean", + describe: + "TBD", + }, }); } -export async function handler( - args: StrictYargsOptionsToInterface -) { - const config = readConfig(args.config, args); - - const body: PostConsumerBody = { +function createBody(args: StrictYargsOptionsToInterface): PostConsumerBody { + return { script_name: args.scriptName, // TODO(soon) is this still the correct usage of the environment? environment_name: args.env ?? "", // API expects empty string as default @@ -64,6 +67,13 @@ export async function handler( }, dead_letter_queue: args.deadLetterQueue, }; +} + +export async function handler( + args: StrictYargsOptionsToInterface +) { + const config = readConfig(args.config, args); + const body = createBody(args); logger.log(`Adding consumer to queue ${args.queueName}.`); await postConsumer(config, args.queueName, body); diff --git a/packages/wrangler/src/queues/cli/commands/create.ts b/packages/wrangler/src/queues/cli/commands/create.ts index f1d354db10ee..edd2e34ec0dd 100644 --- a/packages/wrangler/src/queues/cli/commands/create.ts +++ b/packages/wrangler/src/queues/cli/commands/create.ts @@ -1,25 +1,45 @@ import { readConfig } from "../../../config"; import { logger } from "../../../logger"; -import { createQueue } from "../../client"; +import { createQueue, CreateQueueBody, QueueSettings } from "../../client"; import type { CommonYargsArgv, StrictYargsOptionsToInterface, } from "../../../yargs-types"; export function options(yargs: CommonYargsArgv) { - return yargs.positional("name", { - type: "string", - demandOption: true, - description: "The name of the queue", - }); + return yargs + .positional("name", { + type: "string", + demandOption: true, + description: "The name of the queue", + }) + .options({ + "delivery-delay": { + type: "number", + describe: "TBD", + } + }) + .options({ + "no-delivery-delay": { + type: "boolean", + describe: "TBD", + } + }); +} + +function createBody(args: StrictYargsOptionsToInterface): CreateQueueBody { + return { + queue_name: args.name + } } export async function handler( args: StrictYargsOptionsToInterface ) { const config = readConfig(args.config, args); + const body = createBody(args); logger.log(`Creating queue ${args.name}.`); - await createQueue(config, { queue_name: args.name }); + await createQueue(config, body); logger.log(`Created queue ${args.name}.`); } diff --git a/packages/wrangler/src/queues/client.ts b/packages/wrangler/src/queues/client.ts index 4e814663abfc..81abcc135f9f 100644 --- a/packages/wrangler/src/queues/client.ts +++ b/packages/wrangler/src/queues/client.ts @@ -1,6 +1,5 @@ import { fetchResult } from "../cfetch"; import { type Config } from "../config"; -import { UserError } from "../errors"; import { requireAuth } from "../user"; export async function createQueue( @@ -16,6 +15,11 @@ export async function createQueue( export interface CreateQueueBody { queue_name: string; + settings?: QueueSettings; +} + +export interface QueueSettings { + delivery_delay?: number; } export interface ScriptReference { @@ -42,6 +46,7 @@ export interface QueueResponse { producers_total_count: number; consumers: Consumer[]; consumers_total_count: number; + settings: QueueSettings; } export async function deleteQueue( @@ -97,50 +102,6 @@ export async function postConsumer( ); } -export async function postTypedConsumer( - config: Config, - queueName: string, - body: PostTypedConsumerBody -): Promise { - const accountId = await requireAuth(config); - const queue = await getQueue(config, queueName); - return fetchResult( - `/accounts/${accountId}/queues/${queue.queue_id}/consumers`, - { - method: "POST", - body: JSON.stringify(body), - } - ); -} - -export async function putTypedConsumer( - config: Config, - queueId: string, - consumerId: string, - body: PostTypedConsumerBody -): Promise { - const accountId = await requireAuth(config); - - return fetchResult( - `/accounts/${accountId}/queues/${queueId}/consumers/${consumerId}`, - { - method: "PUT", - body: JSON.stringify(body), - } - ); -} - -export interface TypedConsumerResponse extends Consumer { - queue_name: string; - created_on: string; -} - -export interface PostTypedConsumerBody extends PutConsumerBody { - type: string; - script_name?: string; - environment_name?: string; -} - export interface PutConsumerBody { settings: ConsumerSettings; dead_letter_queue?: string; @@ -156,8 +117,7 @@ export interface ConsumerSettings { max_retries?: number; max_wait_time_ms?: number; max_concurrency?: number | null; - visibility_timeout_ms?: number; - retry_delay?: number; + retry_delay?: number } export interface ConsumerResponse extends PostConsumerBody { @@ -168,22 +128,6 @@ export interface ConsumerResponse extends PostConsumerBody { dead_letter_queue?: string; } -export async function deletePullConsumer( - config: Config, - queueName: string -): Promise { - const accountId = await requireAuth(config); - const queue = await getQueue(config, queueName); - const consumer = queue.consumers[0]; - if (consumer?.type !== "http_pull") { - throw new UserError(`No http_pull consumer exists for queue ${queueName}`); - } - const resource = `/accounts/${accountId}/queues/${queue.queue_id}/consumers/${consumer.consumer_id}`; - return fetchResult(resource, { - method: "DELETE", - }); -} - export async function deleteConsumer( config: Config, queueName: string, From ad9ac1f531d4ee6824161d0d290fbd193963519e Mon Sep 17 00:00:00 2001 From: Pedro Leal Date: Thu, 22 Feb 2024 17:25:21 +0000 Subject: [PATCH 02/17] Unit tests for queues create with delivery delay --- .../wrangler/src/__tests__/queues.test.ts | 54 ++++++++++++++----- .../src/queues/cli/commands/create.ts | 11 +++- pnpm-lock.yaml | 3 ++ 3 files changed, 55 insertions(+), 13 deletions(-) diff --git a/packages/wrangler/src/__tests__/queues.test.ts b/packages/wrangler/src/__tests__/queues.test.ts index 009ef48c4a4b..5a0f0160f07e 100644 --- a/packages/wrangler/src/__tests__/queues.test.ts +++ b/packages/wrangler/src/__tests__/queues.test.ts @@ -153,7 +153,7 @@ describe("wrangler", () => { }); describe("create", () => { - function mockCreateRequest(expectedQueueName: string) { + function mockCreateRequest(expectedQueueName: string, queueSettings: { delivery_delay?: number } | undefined = undefined) { const requests = { count: 0 }; msw.use( @@ -161,10 +161,16 @@ describe("wrangler", () => { "*/accounts/:accountId/workers/queues", async (request, response, context) => { requests.count += 1; + + const body = (await request.json()) as { queue_name: string; + settings: { + delivery_delay: number + }; }; expect(body.queue_name).toEqual(expectedQueueName); + expect(body.settings).toEqual(queueSettings); return response.once( context.json({ success: true, @@ -187,20 +193,24 @@ describe("wrangler", () => { await runWrangler("queues create --help"); expect(std.err).toMatchInlineSnapshot(`""`); expect(std.out).toMatchInlineSnapshot(` - "wrangler queues create +"wrangler queues create - Create a Queue +Create a Queue - Positionals: - name The name of the queue [string] [required] +Positionals: + name The name of the queue [string] [required] - Flags: - -j, --experimental-json-config Experimental: Support wrangler.json [boolean] - -c, --config Path to .toml configuration file [string] - -e, --env Environment to use for operations and .env files [string] - -h, --help Show help [boolean] - -v, --version Show version number [boolean]" - `); +Flags: + -j, --experimental-json-config Experimental: Support wrangler.json [boolean] + -c, --config Path to .toml configuration file [string] + -e, --env Environment to use for operations and .env files [string] + -h, --help Show help [boolean] + -v, --version Show version number [boolean] + +Options: + --delivery-delay TBD [number] + --no-delivery-delay TBD [boolean]" +`); }); it("should create a queue", async () => { @@ -251,6 +261,26 @@ describe("wrangler", () => { " `); }); + + it("should send send queue settings with delivery delay", async () => { + const requests = mockCreateRequest("testQueue", { delivery_delay: 10}); + await runWrangler("queues create testQueue --delivery-delay=10"); + expect(std.out).toMatchInlineSnapshot(` + "Creating queue testQueue. + Created queue testQueue." + `); + expect(requests.count).toEqual(1); + }); + + it("should send send queue settings with 0 delivery delay when noDeliveryDelay is set", async () => { + const requests = mockCreateRequest("testQueue", { delivery_delay: 0}); + await runWrangler("queues create testQueue --no-delivery-delay"); + expect(std.out).toMatchInlineSnapshot(` + "Creating queue testQueue. + Created queue testQueue." + `); + expect(requests.count).toEqual(1); + }); }); describe("delete", () => { diff --git a/packages/wrangler/src/queues/cli/commands/create.ts b/packages/wrangler/src/queues/cli/commands/create.ts index edd2e34ec0dd..22d0997e0992 100644 --- a/packages/wrangler/src/queues/cli/commands/create.ts +++ b/packages/wrangler/src/queues/cli/commands/create.ts @@ -23,14 +23,23 @@ export function options(yargs: CommonYargsArgv) { "no-delivery-delay": { type: "boolean", describe: "TBD", + boolean: true } }); } function createBody(args: StrictYargsOptionsToInterface): CreateQueueBody { - return { + const baseBody: CreateQueueBody = { queue_name: args.name } + + if(args.deliveryDelay != undefined || args.noDeliveryDelay != undefined) { + baseBody.settings = { + delivery_delay: args.noDeliveryDelay !== undefined ? 0 : args.deliveryDelay + } + } + + return baseBody } export async function handler( diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index fd5b2fed4d87..b8526a354093 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -9910,6 +9910,7 @@ packages: /clean-stack@2.2.0: resolution: {integrity: sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==} engines: {node: '>=6'} + requiresBuild: true /clean-stack@4.2.0: resolution: {integrity: sha512-LYv6XPxoyODi36Dp976riBtSY27VmFo+MKqEU9QCCWyTrdEPDog+RWA7xQWHi6Vbp61j5c4cdzzX1NidnwtUWg==} @@ -16088,6 +16089,7 @@ packages: /minipass@4.0.0: resolution: {integrity: sha512-g2Uuh2jEKoht+zvO6vJqXmYpflPqzRBT+Th2h01DKh5z7wbY/AZ2gCQ78cP70YoHPyFdY30YBV5WxgLOEwOykw==} engines: {node: '>=8'} + requiresBuild: true dependencies: yallist: 4.0.0 @@ -16105,6 +16107,7 @@ packages: /minizlib@2.1.2: resolution: {integrity: sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==} engines: {node: '>= 8'} + requiresBuild: true dependencies: minipass: 3.3.6 yallist: 4.0.0 From c64c8d997f93a470a4234f06528e29641e780be4 Mon Sep 17 00:00:00 2001 From: Pedro Leal Date: Fri, 23 Feb 2024 18:37:55 +0000 Subject: [PATCH 03/17] Added error handling for invalid queue settings --- .../cli/commands/consumer/worker/add.ts | 31 ++++++++++++--- .../src/queues/cli/commands/create.ts | 38 ++++++++++++++----- packages/wrangler/src/queues/constants.ts | 2 + packages/wrangler/src/queues/utils.ts | 14 +++++++ 4 files changed, 70 insertions(+), 15 deletions(-) create mode 100644 packages/wrangler/src/queues/constants.ts diff --git a/packages/wrangler/src/queues/cli/commands/consumer/worker/add.ts b/packages/wrangler/src/queues/cli/commands/consumer/worker/add.ts index 9e084d81439d..ffb1404fe869 100644 --- a/packages/wrangler/src/queues/cli/commands/consumer/worker/add.ts +++ b/packages/wrangler/src/queues/cli/commands/consumer/worker/add.ts @@ -1,8 +1,10 @@ import { readConfig } from "../../../../config"; import { logger } from "../../../../logger"; +import { UserError } from "../../../../errors"; import type { PostConsumerBody } from "../../../client"; import { postConsumer } from "../../../client"; import type { CommonYargsArgv, StrictYargsOptionsToInterface } from "../../../../yargs-types"; +import { handleFetchError } from "../../../utils"; export function options(yargs: CommonYargsArgv) { return yargs @@ -53,7 +55,7 @@ export function options(yargs: CommonYargsArgv) { } function createBody(args: StrictYargsOptionsToInterface): PostConsumerBody { - return { + const body = { script_name: args.scriptName, // TODO(soon) is this still the correct usage of the environment? environment_name: args.env ?? "", // API expects empty string as default @@ -66,7 +68,22 @@ function createBody(args: StrictYargsOptionsToInterface): PostCo max_concurrency: args.maxConcurrency, }, dead_letter_queue: args.deadLetterQueue, - }; + } as PostConsumerBody; + + if(args.retryDelay !== undefined && + args.noRetryDelay !== undefined) { + throw new UserError(`Can't specify a retry delay with when noRetryDelay is set.`); + } + + if(args.retryDelay != undefined) { + body.settings.retry_delay = args.retryDelay + } + + if(args.noRetryDelay != undefined) { + body.settings.retry_delay = 0 + } + + return body; } export async function handler( @@ -75,7 +92,11 @@ export async function handler( const config = readConfig(args.config, args); const body = createBody(args); - logger.log(`Adding consumer to queue ${args.queueName}.`); - await postConsumer(config, args.queueName, body); - logger.log(`Added consumer to queue ${args.queueName}.`); + try { + logger.log(`Adding consumer to queue ${args.queueName}.`); + await postConsumer(config, args.queueName, body); + logger.log(`Added consumer to queue ${args.queueName}.`); + } catch(e) { + handleFetchError(e as {code?: number}) + } } diff --git a/packages/wrangler/src/queues/cli/commands/create.ts b/packages/wrangler/src/queues/cli/commands/create.ts index 22d0997e0992..7032c4aea448 100644 --- a/packages/wrangler/src/queues/cli/commands/create.ts +++ b/packages/wrangler/src/queues/cli/commands/create.ts @@ -1,10 +1,13 @@ import { readConfig } from "../../../config"; import { logger } from "../../../logger"; -import { createQueue, CreateQueueBody, QueueSettings } from "../../client"; +import type { CreateQueueBody } from "../../client"; +import { createQueue } from "../../client"; import type { CommonYargsArgv, StrictYargsOptionsToInterface, } from "../../../yargs-types"; +import { UserError } from "../../../errors"; +import { handleFetchError } from "../../utils"; export function options(yargs: CommonYargsArgv) { return yargs @@ -29,17 +32,28 @@ export function options(yargs: CommonYargsArgv) { } function createBody(args: StrictYargsOptionsToInterface): CreateQueueBody { - const baseBody: CreateQueueBody = { + const body: CreateQueueBody = { queue_name: args.name } - if(args.deliveryDelay != undefined || args.noDeliveryDelay != undefined) { - baseBody.settings = { - delivery_delay: args.noDeliveryDelay !== undefined ? 0 : args.deliveryDelay + if(args.deliveryDelay !== undefined && + args.noDeliveryDelay !== undefined) { + throw new UserError(`Can't specify a delivery delay with when noDeliveryDelay is set.`); + } + + if(args.deliveryDelay != undefined) { + body.settings = { + delivery_delay: args.deliveryDelay } } - return baseBody + if(args.noDeliveryDelay != undefined) { + body.settings = { + delivery_delay: 0 + } + } + + return body } export async function handler( @@ -47,8 +61,12 @@ export async function handler( ) { const config = readConfig(args.config, args); const body = createBody(args); - - logger.log(`Creating queue ${args.name}.`); - await createQueue(config, body); - logger.log(`Created queue ${args.name}.`); + try { + logger.log(`Creating queue ${args.name}.`); + await createQueue(config, body); + logger.log(`Created queue ${args.name}.`); + } catch(e) { + handleFetchError(e as {code?: number}) + throw e; + } } diff --git a/packages/wrangler/src/queues/constants.ts b/packages/wrangler/src/queues/constants.ts new file mode 100644 index 000000000000..d60cf3aa739b --- /dev/null +++ b/packages/wrangler/src/queues/constants.ts @@ -0,0 +1,2 @@ +export const INVALID_CONSUMER_SETTINGS_ERROR = 100127; +export const INVALID_QUEUE_SETTINGS_ERROR = 100128; \ No newline at end of file diff --git a/packages/wrangler/src/queues/utils.ts b/packages/wrangler/src/queues/utils.ts index 4f938745598d..f7bb7c2f0959 100644 --- a/packages/wrangler/src/queues/utils.ts +++ b/packages/wrangler/src/queues/utils.ts @@ -1,6 +1,8 @@ import { logger } from "../logger"; import { type ParseError } from "../parse"; import { getAccountId } from "../user"; +import { INVALID_CONSUMER_SETTINGS_ERROR, INVALID_QUEUE_SETTINGS_ERROR } from "./constants"; +import { UserError } from "../errors"; const isFetchError = (err: unknown): err is ParseError => err instanceof Error; @@ -16,3 +18,15 @@ export const HandleUnauthorizedError = async (_msg: string, err: Error) => { } throw err; }; + +export function handleFetchError(e: {code?: number}): void { + if (e.code === INVALID_CONSUMER_SETTINGS_ERROR) { + throw new UserError(`The specified consumer settings are invalid.`); + } + + if (e.code === INVALID_QUEUE_SETTINGS_ERROR) { + throw new UserError(`The specified queue settings are invalid.`); + } + + throw e; +} From 80e1eecc7e5a6546d641cdfe6273aff555c2d1dc Mon Sep 17 00:00:00 2001 From: Pedro Leal Date: Fri, 23 Feb 2024 18:52:43 +0000 Subject: [PATCH 04/17] Helper Text --- .../wrangler/src/__tests__/queues.test.ts | 44 ++++++++++--------- .../cli/commands/consumer/worker/add.ts | 7 ++- .../src/queues/cli/commands/create.ts | 4 +- 3 files changed, 29 insertions(+), 26 deletions(-) diff --git a/packages/wrangler/src/__tests__/queues.test.ts b/packages/wrangler/src/__tests__/queues.test.ts index 5a0f0160f07e..2f512e9fe898 100644 --- a/packages/wrangler/src/__tests__/queues.test.ts +++ b/packages/wrangler/src/__tests__/queues.test.ts @@ -153,7 +153,10 @@ describe("wrangler", () => { }); describe("create", () => { - function mockCreateRequest(expectedQueueName: string, queueSettings: { delivery_delay?: number } | undefined = undefined) { + function mockCreateRequest( + expectedQueueName: string, + queueSettings: { delivery_delay?: number } | undefined = undefined + ) { const requests = { count: 0 }; msw.use( @@ -162,11 +165,10 @@ describe("wrangler", () => { async (request, response, context) => { requests.count += 1; - const body = (await request.json()) as { queue_name: string; settings: { - delivery_delay: number + delivery_delay: number; }; }; expect(body.queue_name).toEqual(expectedQueueName); @@ -193,24 +195,24 @@ describe("wrangler", () => { await runWrangler("queues create --help"); expect(std.err).toMatchInlineSnapshot(`""`); expect(std.out).toMatchInlineSnapshot(` -"wrangler queues create + "wrangler queues create -Create a Queue + Create a Queue -Positionals: - name The name of the queue [string] [required] + Positionals: + name The name of the queue [string] [required] -Flags: - -j, --experimental-json-config Experimental: Support wrangler.json [boolean] - -c, --config Path to .toml configuration file [string] - -e, --env Environment to use for operations and .env files [string] - -h, --help Show help [boolean] - -v, --version Show version number [boolean] + Flags: + -j, --experimental-json-config Experimental: Support wrangler.json [boolean] + -c, --config Path to .toml configuration file [string] + -e, --env Environment to use for operations and .env files [string] + -h, --help Show help [boolean] + -v, --version Show version number [boolean] -Options: - --delivery-delay TBD [number] - --no-delivery-delay TBD [boolean]" -`); + Options: + --delivery-delay How long a published messages should be delayed for, in seconds. Must be a positive integer [number] + --no-delivery-delay Sets published messages have no delay [boolean]" + `); }); it("should create a queue", async () => { @@ -263,7 +265,7 @@ Options: }); it("should send send queue settings with delivery delay", async () => { - const requests = mockCreateRequest("testQueue", { delivery_delay: 10}); + const requests = mockCreateRequest("testQueue", { delivery_delay: 10 }); await runWrangler("queues create testQueue --delivery-delay=10"); expect(std.out).toMatchInlineSnapshot(` "Creating queue testQueue. @@ -273,7 +275,7 @@ Options: }); it("should send send queue settings with 0 delivery delay when noDeliveryDelay is set", async () => { - const requests = mockCreateRequest("testQueue", { delivery_delay: 0}); + const requests = mockCreateRequest("testQueue", { delivery_delay: 0 }); await runWrangler("queues create testQueue --no-delivery-delay"); expect(std.out).toMatchInlineSnapshot(` "Creating queue testQueue. @@ -415,7 +417,9 @@ Options: --batch-timeout Maximum number of seconds to wait to fill a batch with messages [number] --message-retries Maximum number of retries for each message [number] --dead-letter-queue Queue to send messages that failed to be consumed [string] - --max-concurrency The maximum number of concurrent consumer Worker invocations. Must be a positive integer [number]" + --max-concurrency The maximum number of concurrent consumer Worker invocations. Must be a positive integer [number] + --retry-delay How long a retried messages should be delayed for, in seconds. Must be a positive integer [number] + --no-retry-delay Sets retried messages have no delay. [boolean]" `); }); diff --git a/packages/wrangler/src/queues/cli/commands/consumer/worker/add.ts b/packages/wrangler/src/queues/cli/commands/consumer/worker/add.ts index ffb1404fe869..e2ded1cb24d8 100644 --- a/packages/wrangler/src/queues/cli/commands/consumer/worker/add.ts +++ b/packages/wrangler/src/queues/cli/commands/consumer/worker/add.ts @@ -43,13 +43,12 @@ export function options(yargs: CommonYargsArgv) { }, "retry-delay": { type: "number", - describe: - "TBD", + describe: "How long a retried messages should be delayed for, in seconds. Must be a positive integer", }, "no-retry-delay": { type: "boolean", - describe: - "TBD", + describe: "Sets retried messages have no delay.", + boolean: true }, }); } diff --git a/packages/wrangler/src/queues/cli/commands/create.ts b/packages/wrangler/src/queues/cli/commands/create.ts index 7032c4aea448..3b2f467fcf05 100644 --- a/packages/wrangler/src/queues/cli/commands/create.ts +++ b/packages/wrangler/src/queues/cli/commands/create.ts @@ -19,13 +19,13 @@ export function options(yargs: CommonYargsArgv) { .options({ "delivery-delay": { type: "number", - describe: "TBD", + describe: "How long a published messages should be delayed for, in seconds. Must be a positive integer", } }) .options({ "no-delivery-delay": { type: "boolean", - describe: "TBD", + describe: "Sets published messages have no delay", boolean: true } }); From fd2113c5210ea60c88690d04314f3b534cec4544 Mon Sep 17 00:00:00 2001 From: Pedro Leal Date: Mon, 26 Feb 2024 11:34:30 +0000 Subject: [PATCH 05/17] Unit tests for consumer add with retry settings --- .../wrangler/src/__tests__/queues.test.ts | 28 ++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/packages/wrangler/src/__tests__/queues.test.ts b/packages/wrangler/src/__tests__/queues.test.ts index 2f512e9fe898..c2984fe0bfdd 100644 --- a/packages/wrangler/src/__tests__/queues.test.ts +++ b/packages/wrangler/src/__tests__/queues.test.ts @@ -432,6 +432,7 @@ describe("wrangler", () => { max_retries: undefined, max_wait_time_ms: undefined, max_concurrency: undefined, + retry_delay: undefined }, dead_letter_queue: undefined, }; @@ -452,13 +453,38 @@ describe("wrangler", () => { max_retries: 3, max_wait_time_ms: 10 * 1000, max_concurrency: 3, + retry_delay: 10 }, dead_letter_queue: "myDLQ", }; mockPostRequest("testQueue", expectedBody); await runWrangler( - "queues consumer add testQueue testScript --env myEnv --batch-size 20 --batch-timeout 10 --message-retries 3 --max-concurrency 3 --dead-letter-queue myDLQ" + "queues consumer add testQueue testScript --env myEnv --batch-size 20 --batch-timeout 10 --message-retries 3 --max-concurrency 3 --dead-letter-queue myDLQ --retry-delay=10" + ); + expect(std.out).toMatchInlineSnapshot(` + "Adding consumer to queue testQueue. + Added consumer to queue testQueue." + `); + }); + + it("should add a consumer with no delay", async () => { + const expectedBody: PostConsumerBody = { + script_name: "testScript", + environment_name: "myEnv", + settings: { + batch_size: 20, + max_retries: 3, + max_wait_time_ms: 10 * 1000, + max_concurrency: 3, + retry_delay: 0 + }, + dead_letter_queue: "myDLQ", + }; + mockPostRequest("testQueue", expectedBody); + + await runWrangler( + "queues consumer add testQueue testScript --env myEnv --batch-size 20 --batch-timeout 10 --message-retries 3 --max-concurrency 3 --dead-letter-queue myDLQ --no-retry-delay" ); expect(std.out).toMatchInlineSnapshot(` "Adding consumer to queue testQueue. From c8a04f1bd940773865fca299714653890c009c61 Mon Sep 17 00:00:00 2001 From: Pedro Leal Date: Mon, 26 Feb 2024 17:18:19 +0000 Subject: [PATCH 06/17] Updated tests check for no-parameter and parameter --- .changeset/warm-seahorses-trade.md | 5 ++ .../wrangler/src/__tests__/queues.test.ts | 48 +++++++++++++++++-- .../cli/commands/consumer/worker/add.ts | 13 +++-- .../src/queues/cli/commands/create.ts | 21 +++----- 4 files changed, 62 insertions(+), 25 deletions(-) create mode 100644 .changeset/warm-seahorses-trade.md diff --git a/.changeset/warm-seahorses-trade.md b/.changeset/warm-seahorses-trade.md new file mode 100644 index 000000000000..2e4297858f30 --- /dev/null +++ b/.changeset/warm-seahorses-trade.md @@ -0,0 +1,5 @@ +--- +"wrangler": minor +--- + +Added support for queue delivery controls on Queue create and Consumer create. diff --git a/packages/wrangler/src/__tests__/queues.test.ts b/packages/wrangler/src/__tests__/queues.test.ts index c2984fe0bfdd..ccdaa9a87d87 100644 --- a/packages/wrangler/src/__tests__/queues.test.ts +++ b/packages/wrangler/src/__tests__/queues.test.ts @@ -211,7 +211,7 @@ describe("wrangler", () => { Options: --delivery-delay How long a published messages should be delayed for, in seconds. Must be a positive integer [number] - --no-delivery-delay Sets published messages have no delay [boolean]" + --no-delivery-delay Sets published messages to have no delay [boolean]" `); }); @@ -283,6 +283,20 @@ describe("wrangler", () => { `); expect(requests.count).toEqual(1); }); + + it("should show an error with delivery delay and no delivery delay are used", async () => { + const requests = mockCreateRequest("testQueue", { delivery_delay: 0 }); + + await expect( + runWrangler( + "queues create testQueue --no-delivery-delay --delivery-delay=10" + ) + ).rejects.toThrowError( + `Error: can't use --no-delivery-delay with --delivery-delay` + ); + + expect(requests.count).toEqual(0); + }); }); describe("delete", () => { @@ -432,7 +446,7 @@ describe("wrangler", () => { max_retries: undefined, max_wait_time_ms: undefined, max_concurrency: undefined, - retry_delay: undefined + retry_delay: undefined, }, dead_letter_queue: undefined, }; @@ -453,7 +467,7 @@ describe("wrangler", () => { max_retries: 3, max_wait_time_ms: 10 * 1000, max_concurrency: 3, - retry_delay: 10 + retry_delay: 10, }, dead_letter_queue: "myDLQ", }; @@ -477,7 +491,7 @@ describe("wrangler", () => { max_retries: 3, max_wait_time_ms: 10 * 1000, max_concurrency: 3, - retry_delay: 0 + retry_delay: 0, }, dead_letter_queue: "myDLQ", }; @@ -492,6 +506,32 @@ describe("wrangler", () => { `); }); + it("should show an error with retry delay and no retry delay are used", async () => { + const expectedBody: PostConsumerBody = { + script_name: "testScript", + environment_name: "myEnv", + settings: { + batch_size: 20, + max_retries: 3, + max_wait_time_ms: 10 * 1000, + max_concurrency: 3, + retry_delay: 0, + }, + dead_letter_queue: "myDLQ", + }; + const requests = mockPostRequest("testQueue", expectedBody); + + await expect( + runWrangler( + "queues consumer add testQueue testScript --env myEnv --batch-size 20 --batch-timeout 10 --message-retries 3 --max-concurrency 3 --dead-letter-queue myDLQ --no-retry-delay --retry-delay=10" + ) + ).rejects.toThrowError( + `Error: can't use --no-retry-delay with --retry-delay` + ); + + expect(requests.count).toEqual(0); + }); + it("should show link to dash when not enabled", async () => { const queueName = "testQueue"; msw.use( diff --git a/packages/wrangler/src/queues/cli/commands/consumer/worker/add.ts b/packages/wrangler/src/queues/cli/commands/consumer/worker/add.ts index e2ded1cb24d8..76dea5e68742 100644 --- a/packages/wrangler/src/queues/cli/commands/consumer/worker/add.ts +++ b/packages/wrangler/src/queues/cli/commands/consumer/worker/add.ts @@ -44,6 +44,7 @@ export function options(yargs: CommonYargsArgv) { "retry-delay": { type: "number", describe: "How long a retried messages should be delayed for, in seconds. Must be a positive integer", + number: true, }, "no-retry-delay": { type: "boolean", @@ -69,19 +70,17 @@ function createBody(args: StrictYargsOptionsToInterface): PostCo dead_letter_queue: args.deadLetterQueue, } as PostConsumerBody; - if(args.retryDelay !== undefined && - args.noRetryDelay !== undefined) { - throw new UserError(`Can't specify a retry delay with when noRetryDelay is set.`); + + // Workaround, Yargs does not play nicely with both --parameter and --no-parameter set. + // Negating a number parameter returns 0, making retryDelay an array with [0, ] + if(Array.isArray(args.retryDelay)) { + throw new UserError(`Error: can't use --no-retry-delay with --retry-delay`); } if(args.retryDelay != undefined) { body.settings.retry_delay = args.retryDelay } - if(args.noRetryDelay != undefined) { - body.settings.retry_delay = 0 - } - return body; } diff --git a/packages/wrangler/src/queues/cli/commands/create.ts b/packages/wrangler/src/queues/cli/commands/create.ts index 3b2f467fcf05..6e77ec23c0fe 100644 --- a/packages/wrangler/src/queues/cli/commands/create.ts +++ b/packages/wrangler/src/queues/cli/commands/create.ts @@ -20,13 +20,11 @@ export function options(yargs: CommonYargsArgv) { "delivery-delay": { type: "number", describe: "How long a published messages should be delayed for, in seconds. Must be a positive integer", - } - }) - .options({ + }, "no-delivery-delay": { type: "boolean", - describe: "Sets published messages have no delay", - boolean: true + describe: "Sets published messages to have no delay", + boolean: true, } }); } @@ -36,9 +34,10 @@ function createBody(args: StrictYargsOptionsToInterface): Create queue_name: args.name } - if(args.deliveryDelay !== undefined && - args.noDeliveryDelay !== undefined) { - throw new UserError(`Can't specify a delivery delay with when noDeliveryDelay is set.`); + // Workaround, Yargs does not play nicely with both --parameter and --no-parameter set. + // Negating a number parameter returns 0, making deliveryDelay an array with [0, ] + if(Array.isArray(args.deliveryDelay)) { + throw new UserError(`Error: can't use --no-delivery-delay with --delivery-delay`); } if(args.deliveryDelay != undefined) { @@ -47,12 +46,6 @@ function createBody(args: StrictYargsOptionsToInterface): Create } } - if(args.noDeliveryDelay != undefined) { - body.settings = { - delivery_delay: 0 - } - } - return body } From cb458be42a556e923cb704c89fc9f273e212ef6e Mon Sep 17 00:00:00 2001 From: Pedro Leal Date: Tue, 27 Feb 2024 10:54:26 +0000 Subject: [PATCH 07/17] PR suggestions --- packages/wrangler/src/__tests__/queues.test.ts | 13 +++++-------- .../src/queues/cli/commands/consumer/worker/add.ts | 7 ++++--- packages/wrangler/src/queues/cli/commands/create.ts | 4 ++-- 3 files changed, 11 insertions(+), 13 deletions(-) diff --git a/packages/wrangler/src/__tests__/queues.test.ts b/packages/wrangler/src/__tests__/queues.test.ts index ccdaa9a87d87..21b5c4a762cd 100644 --- a/packages/wrangler/src/__tests__/queues.test.ts +++ b/packages/wrangler/src/__tests__/queues.test.ts @@ -287,12 +287,9 @@ describe("wrangler", () => { it("should show an error with delivery delay and no delivery delay are used", async () => { const requests = mockCreateRequest("testQueue", { delivery_delay: 0 }); - await expect( - runWrangler( - "queues create testQueue --no-delivery-delay --delivery-delay=10" - ) - ).rejects.toThrowError( - `Error: can't use --no-delivery-delay with --delivery-delay` + expect( + runWrangler("queues create testQueue --no-delivery-delay --delivery-delay=10")) + .toThrowErrorMatchingInlineSnapshot(`"Error: can't use --no-delivery-delay with --delivery-delay"` ); expect(requests.count).toEqual(0); @@ -525,8 +522,8 @@ describe("wrangler", () => { runWrangler( "queues consumer add testQueue testScript --env myEnv --batch-size 20 --batch-timeout 10 --message-retries 3 --max-concurrency 3 --dead-letter-queue myDLQ --no-retry-delay --retry-delay=10" ) - ).rejects.toThrowError( - `Error: can't use --no-retry-delay with --retry-delay` + ).rejects.toThrowErrorMatchingInlineSnapshot( + `"Error: can't use --no-retry-delay with --retry-delay"` ); expect(requests.count).toEqual(0); diff --git a/packages/wrangler/src/queues/cli/commands/consumer/worker/add.ts b/packages/wrangler/src/queues/cli/commands/consumer/worker/add.ts index 76dea5e68742..4d4b7d5bfd96 100644 --- a/packages/wrangler/src/queues/cli/commands/consumer/worker/add.ts +++ b/packages/wrangler/src/queues/cli/commands/consumer/worker/add.ts @@ -51,11 +51,12 @@ export function options(yargs: CommonYargsArgv) { describe: "Sets retried messages have no delay.", boolean: true }, - }); + }) + .conflicts('retry-delay', 'no-retry-delay') } function createBody(args: StrictYargsOptionsToInterface): PostConsumerBody { - const body = { + const body: PostConsumerBody = { script_name: args.scriptName, // TODO(soon) is this still the correct usage of the environment? environment_name: args.env ?? "", // API expects empty string as default @@ -68,7 +69,7 @@ function createBody(args: StrictYargsOptionsToInterface): PostCo max_concurrency: args.maxConcurrency, }, dead_letter_queue: args.deadLetterQueue, - } as PostConsumerBody; + }; // Workaround, Yargs does not play nicely with both --parameter and --no-parameter set. diff --git a/packages/wrangler/src/queues/cli/commands/create.ts b/packages/wrangler/src/queues/cli/commands/create.ts index 6e77ec23c0fe..d62a05164c56 100644 --- a/packages/wrangler/src/queues/cli/commands/create.ts +++ b/packages/wrangler/src/queues/cli/commands/create.ts @@ -26,7 +26,8 @@ export function options(yargs: CommonYargsArgv) { describe: "Sets published messages to have no delay", boolean: true, } - }); + }) + .conflicts('delivery-delay', 'no-delivery-delay') } function createBody(args: StrictYargsOptionsToInterface): CreateQueueBody { @@ -60,6 +61,5 @@ export async function handler( logger.log(`Created queue ${args.name}.`); } catch(e) { handleFetchError(e as {code?: number}) - throw e; } } From b6ca6b653837ac042da30f2301ccdffc6ad5a434 Mon Sep 17 00:00:00 2001 From: Pedro Leal Date: Tue, 27 Feb 2024 19:35:48 +0000 Subject: [PATCH 08/17] Changed yargs.fail error handling --- .../wrangler/src/__tests__/queues.test.ts | 25 ++++++++++++++----- .../cli/commands/consumer/worker/add.ts | 4 +-- .../src/queues/cli/commands/create.ts | 12 ++++----- .../wrangler/src/queues/cli/commands/index.ts | 1 + packages/wrangler/src/queues/utils.ts | 2 +- 5 files changed, 29 insertions(+), 15 deletions(-) diff --git a/packages/wrangler/src/__tests__/queues.test.ts b/packages/wrangler/src/__tests__/queues.test.ts index 21b5c4a762cd..d2a1b98e6ca9 100644 --- a/packages/wrangler/src/__tests__/queues.test.ts +++ b/packages/wrangler/src/__tests__/queues.test.ts @@ -1,6 +1,8 @@ import { rest } from "msw"; import { mockAccountId, mockApiToken } from "./helpers/mock-account-id"; import { mockConsoleMethods } from "./helpers/mock-console"; +import { clearDialogs } from "./helpers/mock-dialogs"; +import { useMockIsTTY } from "./helpers/mock-istty"; import { msw } from "./helpers/msw"; import { runInTempDir } from "./helpers/run-in-tmp"; import { runWrangler } from "./helpers/run-wrangler"; @@ -16,6 +18,14 @@ describe("wrangler", () => { runInTempDir(); const std = mockConsoleMethods(); + const { setIsTTY } = useMockIsTTY(); + beforeEach(() => { + setIsTTY(true); + }); + afterEach(() => { + clearDialogs(); + }); + describe("queues", () => { it("should show the correct help text", async () => { await runWrangler("queues --help"); @@ -210,8 +220,8 @@ describe("wrangler", () => { -v, --version Show version number [boolean] Options: - --delivery-delay How long a published messages should be delayed for, in seconds. Must be a positive integer [number] - --no-delivery-delay Sets published messages to have no delay [boolean]" + --no-delivery-delay Sets published messages to have no delay [boolean] + --delivery-delay How long a published messages should be delayed for, in seconds. Must be a positive integer [number]" `); }); @@ -287,9 +297,12 @@ describe("wrangler", () => { it("should show an error with delivery delay and no delivery delay are used", async () => { const requests = mockCreateRequest("testQueue", { delivery_delay: 0 }); - expect( - runWrangler("queues create testQueue --no-delivery-delay --delivery-delay=10")) - .toThrowErrorMatchingInlineSnapshot(`"Error: can't use --no-delivery-delay with --delivery-delay"` + await expect( + runWrangler( + "queues create testQueue --no-delivery-delay --delivery-delay=10" + ) + ).rejects.toThrowErrorMatchingInlineSnapshot( + `"Error: can't use more than a delay setting."` ); expect(requests.count).toEqual(0); @@ -523,7 +536,7 @@ describe("wrangler", () => { "queues consumer add testQueue testScript --env myEnv --batch-size 20 --batch-timeout 10 --message-retries 3 --max-concurrency 3 --dead-letter-queue myDLQ --no-retry-delay --retry-delay=10" ) ).rejects.toThrowErrorMatchingInlineSnapshot( - `"Error: can't use --no-retry-delay with --retry-delay"` + `"Error: can't use more than a delay setting."` ); expect(requests.count).toEqual(0); diff --git a/packages/wrangler/src/queues/cli/commands/consumer/worker/add.ts b/packages/wrangler/src/queues/cli/commands/consumer/worker/add.ts index 4d4b7d5bfd96..d16a82179201 100644 --- a/packages/wrangler/src/queues/cli/commands/consumer/worker/add.ts +++ b/packages/wrangler/src/queues/cli/commands/consumer/worker/add.ts @@ -1,10 +1,10 @@ import { readConfig } from "../../../../config"; import { logger } from "../../../../logger"; -import { UserError } from "../../../../errors"; import type { PostConsumerBody } from "../../../client"; import { postConsumer } from "../../../client"; import type { CommonYargsArgv, StrictYargsOptionsToInterface } from "../../../../yargs-types"; import { handleFetchError } from "../../../utils"; +import { CommandLineArgsError } from "../../../../index"; export function options(yargs: CommonYargsArgv) { return yargs @@ -75,7 +75,7 @@ function createBody(args: StrictYargsOptionsToInterface): PostCo // Workaround, Yargs does not play nicely with both --parameter and --no-parameter set. // Negating a number parameter returns 0, making retryDelay an array with [0, ] if(Array.isArray(args.retryDelay)) { - throw new UserError(`Error: can't use --no-retry-delay with --retry-delay`); + throw new CommandLineArgsError(`Error: can't use more than a delay setting.`); } if(args.retryDelay != undefined) { diff --git a/packages/wrangler/src/queues/cli/commands/create.ts b/packages/wrangler/src/queues/cli/commands/create.ts index d62a05164c56..234d88b9de6b 100644 --- a/packages/wrangler/src/queues/cli/commands/create.ts +++ b/packages/wrangler/src/queues/cli/commands/create.ts @@ -6,8 +6,8 @@ import type { CommonYargsArgv, StrictYargsOptionsToInterface, } from "../../../yargs-types"; -import { UserError } from "../../../errors"; import { handleFetchError } from "../../utils"; +import { CommandLineArgsError } from "../../../index"; export function options(yargs: CommonYargsArgv) { return yargs @@ -17,14 +17,14 @@ export function options(yargs: CommonYargsArgv) { description: "The name of the queue", }) .options({ - "delivery-delay": { - type: "number", - describe: "How long a published messages should be delayed for, in seconds. Must be a positive integer", - }, "no-delivery-delay": { type: "boolean", describe: "Sets published messages to have no delay", boolean: true, + }, + "delivery-delay": { + type: "number", + describe: "How long a published messages should be delayed for, in seconds. Must be a positive integer", } }) .conflicts('delivery-delay', 'no-delivery-delay') @@ -38,7 +38,7 @@ function createBody(args: StrictYargsOptionsToInterface): Create // Workaround, Yargs does not play nicely with both --parameter and --no-parameter set. // Negating a number parameter returns 0, making deliveryDelay an array with [0, ] if(Array.isArray(args.deliveryDelay)) { - throw new UserError(`Error: can't use --no-delivery-delay with --delivery-delay`); + throw new CommandLineArgsError(`Error: can't use more than a delay setting.`); } if(args.deliveryDelay != undefined) { diff --git a/packages/wrangler/src/queues/cli/commands/index.ts b/packages/wrangler/src/queues/cli/commands/index.ts index 13ab2699b2e1..3f589f4d205c 100644 --- a/packages/wrangler/src/queues/cli/commands/index.ts +++ b/packages/wrangler/src/queues/cli/commands/index.ts @@ -4,6 +4,7 @@ import { handler as createHandler, options as createOptions } from "./create"; import { handler as deleteHandler, options as deleteOptions } from "./delete"; import { handler as listHandler, options as listOptions } from "./list"; import type { CommonYargsArgv } from "../../../yargs-types"; +import { CommandLineArgsError, printWranglerBanner } from "../../../index"; export function queues(yargs: CommonYargsArgv) { yargs.command("list", "List Queues", listOptions, listHandler); diff --git a/packages/wrangler/src/queues/utils.ts b/packages/wrangler/src/queues/utils.ts index f7bb7c2f0959..73dbc0e7ab1a 100644 --- a/packages/wrangler/src/queues/utils.ts +++ b/packages/wrangler/src/queues/utils.ts @@ -16,7 +16,7 @@ export const HandleUnauthorizedError = async (_msg: string, err: Error) => { ); } } - throw err; + return err; }; export function handleFetchError(e: {code?: number}): void { From 4b998c93c718bbbd5bb9014b2fb3cbf836572a56 Mon Sep 17 00:00:00 2001 From: Pedro Leal Date: Wed, 28 Feb 2024 17:22:56 +0000 Subject: [PATCH 09/17] Removed delivery delay from create consumer and queue --- .../wrangler/src/__tests__/queues.test.ts | 57 +++++-------------- .../cli/commands/consumer/worker/add.ts | 10 +--- .../src/queues/cli/commands/create.ts | 8 +-- .../wrangler/src/queues/cli/commands/index.ts | 1 - 4 files changed, 18 insertions(+), 58 deletions(-) diff --git a/packages/wrangler/src/__tests__/queues.test.ts b/packages/wrangler/src/__tests__/queues.test.ts index d2a1b98e6ca9..16e821890e72 100644 --- a/packages/wrangler/src/__tests__/queues.test.ts +++ b/packages/wrangler/src/__tests__/queues.test.ts @@ -106,6 +106,9 @@ describe("wrangler", () => { producers_total_count: 0, consumers: [], consumers_total_count: 0, + settings: { + delivery_delay: 0 + } }, { queue_id: "def19fa3787741579c9088eb850474af", @@ -116,6 +119,9 @@ describe("wrangler", () => { producers_total_count: 0, consumers: [], consumers_total_count: 0, + settings: { + delivery_delay: 0 + } }, ]; const expectedPage = 1; @@ -145,6 +151,9 @@ describe("wrangler", () => { producers_total_count: 0, consumers: [], consumers_total_count: 0, + settings: { + delivery_delay: 0 + } }, ]; const expectedPage = 2; @@ -220,8 +229,7 @@ describe("wrangler", () => { -v, --version Show version number [boolean] Options: - --no-delivery-delay Sets published messages to have no delay [boolean] - --delivery-delay How long a published messages should be delayed for, in seconds. Must be a positive integer [number]" + --delivery-delay How long a published messages should be delayed for, in seconds. Must be a positive integer [number]" `); }); @@ -284,22 +292,12 @@ describe("wrangler", () => { expect(requests.count).toEqual(1); }); - it("should send send queue settings with 0 delivery delay when noDeliveryDelay is set", async () => { - const requests = mockCreateRequest("testQueue", { delivery_delay: 0 }); - await runWrangler("queues create testQueue --no-delivery-delay"); - expect(std.out).toMatchInlineSnapshot(` - "Creating queue testQueue. - Created queue testQueue." - `); - expect(requests.count).toEqual(1); - }); - - it("should show an error with delivery delay and no delivery delay are used", async () => { + it("should show an error when two delivery delays are set", async () => { const requests = mockCreateRequest("testQueue", { delivery_delay: 0 }); await expect( runWrangler( - "queues create testQueue --no-delivery-delay --delivery-delay=10" + "queues create testQueue --delivery-delay=5 --delivery-delay=10" ) ).rejects.toThrowErrorMatchingInlineSnapshot( `"Error: can't use more than a delay setting."` @@ -442,8 +440,7 @@ describe("wrangler", () => { --message-retries Maximum number of retries for each message [number] --dead-letter-queue Queue to send messages that failed to be consumed [string] --max-concurrency The maximum number of concurrent consumer Worker invocations. Must be a positive integer [number] - --retry-delay How long a retried messages should be delayed for, in seconds. Must be a positive integer [number] - --no-retry-delay Sets retried messages have no delay. [boolean]" + --retry-delay How long a retried messages should be delayed for, in seconds. Must be a positive integer [number]" `); }); @@ -492,31 +489,7 @@ describe("wrangler", () => { `); }); - it("should add a consumer with no delay", async () => { - const expectedBody: PostConsumerBody = { - script_name: "testScript", - environment_name: "myEnv", - settings: { - batch_size: 20, - max_retries: 3, - max_wait_time_ms: 10 * 1000, - max_concurrency: 3, - retry_delay: 0, - }, - dead_letter_queue: "myDLQ", - }; - mockPostRequest("testQueue", expectedBody); - - await runWrangler( - "queues consumer add testQueue testScript --env myEnv --batch-size 20 --batch-timeout 10 --message-retries 3 --max-concurrency 3 --dead-letter-queue myDLQ --no-retry-delay" - ); - expect(std.out).toMatchInlineSnapshot(` - "Adding consumer to queue testQueue. - Added consumer to queue testQueue." - `); - }); - - it("should show an error with retry delay and no retry delay are used", async () => { + it("should show an error when two retry delays are set", async () => { const expectedBody: PostConsumerBody = { script_name: "testScript", environment_name: "myEnv", @@ -533,7 +506,7 @@ describe("wrangler", () => { await expect( runWrangler( - "queues consumer add testQueue testScript --env myEnv --batch-size 20 --batch-timeout 10 --message-retries 3 --max-concurrency 3 --dead-letter-queue myDLQ --no-retry-delay --retry-delay=10" + "queues consumer add testQueue testScript --env myEnv --batch-size 20 --batch-timeout 10 --message-retries 3 --max-concurrency 3 --dead-letter-queue myDLQ --retry-delay=5 --retry-delay=10" ) ).rejects.toThrowErrorMatchingInlineSnapshot( `"Error: can't use more than a delay setting."` diff --git a/packages/wrangler/src/queues/cli/commands/consumer/worker/add.ts b/packages/wrangler/src/queues/cli/commands/consumer/worker/add.ts index d16a82179201..4723f289aca0 100644 --- a/packages/wrangler/src/queues/cli/commands/consumer/worker/add.ts +++ b/packages/wrangler/src/queues/cli/commands/consumer/worker/add.ts @@ -45,14 +45,8 @@ export function options(yargs: CommonYargsArgv) { type: "number", describe: "How long a retried messages should be delayed for, in seconds. Must be a positive integer", number: true, - }, - "no-retry-delay": { - type: "boolean", - describe: "Sets retried messages have no delay.", - boolean: true - }, - }) - .conflicts('retry-delay', 'no-retry-delay') + } + }); } function createBody(args: StrictYargsOptionsToInterface): PostConsumerBody { diff --git a/packages/wrangler/src/queues/cli/commands/create.ts b/packages/wrangler/src/queues/cli/commands/create.ts index 234d88b9de6b..792aaed45b26 100644 --- a/packages/wrangler/src/queues/cli/commands/create.ts +++ b/packages/wrangler/src/queues/cli/commands/create.ts @@ -17,17 +17,11 @@ export function options(yargs: CommonYargsArgv) { description: "The name of the queue", }) .options({ - "no-delivery-delay": { - type: "boolean", - describe: "Sets published messages to have no delay", - boolean: true, - }, "delivery-delay": { type: "number", describe: "How long a published messages should be delayed for, in seconds. Must be a positive integer", } - }) - .conflicts('delivery-delay', 'no-delivery-delay') + }); } function createBody(args: StrictYargsOptionsToInterface): CreateQueueBody { diff --git a/packages/wrangler/src/queues/cli/commands/index.ts b/packages/wrangler/src/queues/cli/commands/index.ts index 3f589f4d205c..13ab2699b2e1 100644 --- a/packages/wrangler/src/queues/cli/commands/index.ts +++ b/packages/wrangler/src/queues/cli/commands/index.ts @@ -4,7 +4,6 @@ import { handler as createHandler, options as createOptions } from "./create"; import { handler as deleteHandler, options as deleteOptions } from "./delete"; import { handler as listHandler, options as listOptions } from "./list"; import type { CommonYargsArgv } from "../../../yargs-types"; -import { CommandLineArgsError, printWranglerBanner } from "../../../index"; export function queues(yargs: CommonYargsArgv) { yargs.command("list", "List Queues", listOptions, listHandler); From f48ccb1c365333d2cefef5a2ec665bf54e0447a1 Mon Sep 17 00:00:00 2001 From: Pedro Leal Date: Wed, 28 Feb 2024 18:07:06 +0000 Subject: [PATCH 10/17] Prettier run --- .../wrangler/src/__tests__/queues.test.ts | 12 ++--- .../cli/commands/consumer/worker/add.ts | 33 ++++++++----- .../src/queues/cli/commands/create.ts | 47 ++++++++++--------- packages/wrangler/src/queues/client.ts | 2 +- packages/wrangler/src/queues/constants.ts | 2 +- packages/wrangler/src/queues/utils.ts | 9 ++-- 6 files changed, 60 insertions(+), 45 deletions(-) diff --git a/packages/wrangler/src/__tests__/queues.test.ts b/packages/wrangler/src/__tests__/queues.test.ts index 16e821890e72..3ef409438381 100644 --- a/packages/wrangler/src/__tests__/queues.test.ts +++ b/packages/wrangler/src/__tests__/queues.test.ts @@ -107,8 +107,8 @@ describe("wrangler", () => { consumers: [], consumers_total_count: 0, settings: { - delivery_delay: 0 - } + delivery_delay: 0, + }, }, { queue_id: "def19fa3787741579c9088eb850474af", @@ -120,8 +120,8 @@ describe("wrangler", () => { consumers: [], consumers_total_count: 0, settings: { - delivery_delay: 0 - } + delivery_delay: 0, + }, }, ]; const expectedPage = 1; @@ -152,8 +152,8 @@ describe("wrangler", () => { consumers: [], consumers_total_count: 0, settings: { - delivery_delay: 0 - } + delivery_delay: 0, + }, }, ]; const expectedPage = 2; diff --git a/packages/wrangler/src/queues/cli/commands/consumer/worker/add.ts b/packages/wrangler/src/queues/cli/commands/consumer/worker/add.ts index 4723f289aca0..0a596774e899 100644 --- a/packages/wrangler/src/queues/cli/commands/consumer/worker/add.ts +++ b/packages/wrangler/src/queues/cli/commands/consumer/worker/add.ts @@ -1,10 +1,13 @@ import { readConfig } from "../../../../config"; +import { CommandLineArgsError } from "../../../../index"; import { logger } from "../../../../logger"; -import type { PostConsumerBody } from "../../../client"; import { postConsumer } from "../../../client"; -import type { CommonYargsArgv, StrictYargsOptionsToInterface } from "../../../../yargs-types"; import { handleFetchError } from "../../../utils"; -import { CommandLineArgsError } from "../../../../index"; +import type { + CommonYargsArgv, + StrictYargsOptionsToInterface, +} from "../../../../yargs-types"; +import type { PostConsumerBody } from "../../../client"; export function options(yargs: CommonYargsArgv) { return yargs @@ -43,13 +46,16 @@ export function options(yargs: CommonYargsArgv) { }, "retry-delay": { type: "number", - describe: "How long a retried messages should be delayed for, in seconds. Must be a positive integer", + describe: + "How long a retried messages should be delayed for, in seconds. Must be a positive integer", number: true, - } + }, }); } -function createBody(args: StrictYargsOptionsToInterface): PostConsumerBody { +function createBody( + args: StrictYargsOptionsToInterface +): PostConsumerBody { const body: PostConsumerBody = { script_name: args.scriptName, // TODO(soon) is this still the correct usage of the environment? @@ -65,15 +71,16 @@ function createBody(args: StrictYargsOptionsToInterface): PostCo dead_letter_queue: args.deadLetterQueue, }; - // Workaround, Yargs does not play nicely with both --parameter and --no-parameter set. // Negating a number parameter returns 0, making retryDelay an array with [0, ] - if(Array.isArray(args.retryDelay)) { - throw new CommandLineArgsError(`Error: can't use more than a delay setting.`); + if (Array.isArray(args.retryDelay)) { + throw new CommandLineArgsError( + `Error: can't use more than a delay setting.` + ); } - if(args.retryDelay != undefined) { - body.settings.retry_delay = args.retryDelay + if (args.retryDelay != undefined) { + body.settings.retry_delay = args.retryDelay; } return body; @@ -89,7 +96,7 @@ export async function handler( logger.log(`Adding consumer to queue ${args.queueName}.`); await postConsumer(config, args.queueName, body); logger.log(`Added consumer to queue ${args.queueName}.`); - } catch(e) { - handleFetchError(e as {code?: number}) + } catch (e) { + handleFetchError(e as { code?: number }); } } diff --git a/packages/wrangler/src/queues/cli/commands/create.ts b/packages/wrangler/src/queues/cli/commands/create.ts index 792aaed45b26..81fde5b48d4e 100644 --- a/packages/wrangler/src/queues/cli/commands/create.ts +++ b/packages/wrangler/src/queues/cli/commands/create.ts @@ -1,47 +1,52 @@ import { readConfig } from "../../../config"; +import { CommandLineArgsError } from "../../../index"; import { logger } from "../../../logger"; -import type { CreateQueueBody } from "../../client"; import { createQueue } from "../../client"; +import { handleFetchError } from "../../utils"; import type { CommonYargsArgv, StrictYargsOptionsToInterface, } from "../../../yargs-types"; -import { handleFetchError } from "../../utils"; -import { CommandLineArgsError } from "../../../index"; +import type { CreateQueueBody } from "../../client"; export function options(yargs: CommonYargsArgv) { return yargs - .positional("name", { - type: "string", - demandOption: true, - description: "The name of the queue", - }) + .positional("name", { + type: "string", + demandOption: true, + description: "The name of the queue", + }) .options({ "delivery-delay": { type: "number", - describe: "How long a published messages should be delayed for, in seconds. Must be a positive integer", - } + describe: + "How long a published messages should be delayed for, in seconds. Must be a positive integer", + }, }); } -function createBody(args: StrictYargsOptionsToInterface): CreateQueueBody { +function createBody( + args: StrictYargsOptionsToInterface +): CreateQueueBody { const body: CreateQueueBody = { - queue_name: args.name - } + queue_name: args.name, + }; // Workaround, Yargs does not play nicely with both --parameter and --no-parameter set. // Negating a number parameter returns 0, making deliveryDelay an array with [0, ] - if(Array.isArray(args.deliveryDelay)) { - throw new CommandLineArgsError(`Error: can't use more than a delay setting.`); + if (Array.isArray(args.deliveryDelay)) { + throw new CommandLineArgsError( + `Error: can't use more than a delay setting.` + ); } - if(args.deliveryDelay != undefined) { + if (args.deliveryDelay != undefined) { body.settings = { - delivery_delay: args.deliveryDelay - } + delivery_delay: args.deliveryDelay, + }; } - return body + return body; } export async function handler( @@ -53,7 +58,7 @@ export async function handler( logger.log(`Creating queue ${args.name}.`); await createQueue(config, body); logger.log(`Created queue ${args.name}.`); - } catch(e) { - handleFetchError(e as {code?: number}) + } catch (e) { + handleFetchError(e as { code?: number }); } } diff --git a/packages/wrangler/src/queues/client.ts b/packages/wrangler/src/queues/client.ts index 81abcc135f9f..c69ddc369164 100644 --- a/packages/wrangler/src/queues/client.ts +++ b/packages/wrangler/src/queues/client.ts @@ -117,7 +117,7 @@ export interface ConsumerSettings { max_retries?: number; max_wait_time_ms?: number; max_concurrency?: number | null; - retry_delay?: number + retry_delay?: number; } export interface ConsumerResponse extends PostConsumerBody { diff --git a/packages/wrangler/src/queues/constants.ts b/packages/wrangler/src/queues/constants.ts index d60cf3aa739b..dd47d23e2e42 100644 --- a/packages/wrangler/src/queues/constants.ts +++ b/packages/wrangler/src/queues/constants.ts @@ -1,2 +1,2 @@ export const INVALID_CONSUMER_SETTINGS_ERROR = 100127; -export const INVALID_QUEUE_SETTINGS_ERROR = 100128; \ No newline at end of file +export const INVALID_QUEUE_SETTINGS_ERROR = 100128; diff --git a/packages/wrangler/src/queues/utils.ts b/packages/wrangler/src/queues/utils.ts index 73dbc0e7ab1a..9df60901ba31 100644 --- a/packages/wrangler/src/queues/utils.ts +++ b/packages/wrangler/src/queues/utils.ts @@ -1,8 +1,11 @@ +import { UserError } from "../errors"; import { logger } from "../logger"; import { type ParseError } from "../parse"; import { getAccountId } from "../user"; -import { INVALID_CONSUMER_SETTINGS_ERROR, INVALID_QUEUE_SETTINGS_ERROR } from "./constants"; -import { UserError } from "../errors"; +import { + INVALID_CONSUMER_SETTINGS_ERROR, + INVALID_QUEUE_SETTINGS_ERROR, +} from "./constants"; const isFetchError = (err: unknown): err is ParseError => err instanceof Error; @@ -19,7 +22,7 @@ export const HandleUnauthorizedError = async (_msg: string, err: Error) => { return err; }; -export function handleFetchError(e: {code?: number}): void { +export function handleFetchError(e: { code?: number }): void { if (e.code === INVALID_CONSUMER_SETTINGS_ERROR) { throw new UserError(`The specified consumer settings are invalid.`); } From b4a3305bcb7646f0813ac7d414b32cc883091759 Mon Sep 17 00:00:00 2001 From: Pedro Leal Date: Wed, 28 Feb 2024 18:18:37 +0000 Subject: [PATCH 11/17] Removed stale comment --- packages/wrangler/src/__tests__/queues.test.ts | 12 +----------- .../src/queues/cli/commands/consumer/worker/add.ts | 2 -- packages/wrangler/src/queues/cli/commands/create.ts | 2 -- 3 files changed, 1 insertion(+), 15 deletions(-) diff --git a/packages/wrangler/src/__tests__/queues.test.ts b/packages/wrangler/src/__tests__/queues.test.ts index 3ef409438381..3fa59b89d30b 100644 --- a/packages/wrangler/src/__tests__/queues.test.ts +++ b/packages/wrangler/src/__tests__/queues.test.ts @@ -1,8 +1,6 @@ import { rest } from "msw"; import { mockAccountId, mockApiToken } from "./helpers/mock-account-id"; import { mockConsoleMethods } from "./helpers/mock-console"; -import { clearDialogs } from "./helpers/mock-dialogs"; -import { useMockIsTTY } from "./helpers/mock-istty"; import { msw } from "./helpers/msw"; import { runInTempDir } from "./helpers/run-in-tmp"; import { runWrangler } from "./helpers/run-wrangler"; @@ -18,14 +16,6 @@ describe("wrangler", () => { runInTempDir(); const std = mockConsoleMethods(); - const { setIsTTY } = useMockIsTTY(); - beforeEach(() => { - setIsTTY(true); - }); - afterEach(() => { - clearDialogs(); - }); - describe("queues", () => { it("should show the correct help text", async () => { await runWrangler("queues --help"); @@ -282,7 +272,7 @@ describe("wrangler", () => { `); }); - it("should send send queue settings with delivery delay", async () => { + it("should send queue settings with delivery delay", async () => { const requests = mockCreateRequest("testQueue", { delivery_delay: 10 }); await runWrangler("queues create testQueue --delivery-delay=10"); expect(std.out).toMatchInlineSnapshot(` diff --git a/packages/wrangler/src/queues/cli/commands/consumer/worker/add.ts b/packages/wrangler/src/queues/cli/commands/consumer/worker/add.ts index 0a596774e899..d4b43bff2d4e 100644 --- a/packages/wrangler/src/queues/cli/commands/consumer/worker/add.ts +++ b/packages/wrangler/src/queues/cli/commands/consumer/worker/add.ts @@ -71,8 +71,6 @@ function createBody( dead_letter_queue: args.deadLetterQueue, }; - // Workaround, Yargs does not play nicely with both --parameter and --no-parameter set. - // Negating a number parameter returns 0, making retryDelay an array with [0, ] if (Array.isArray(args.retryDelay)) { throw new CommandLineArgsError( `Error: can't use more than a delay setting.` diff --git a/packages/wrangler/src/queues/cli/commands/create.ts b/packages/wrangler/src/queues/cli/commands/create.ts index 81fde5b48d4e..0df51168db25 100644 --- a/packages/wrangler/src/queues/cli/commands/create.ts +++ b/packages/wrangler/src/queues/cli/commands/create.ts @@ -32,8 +32,6 @@ function createBody( queue_name: args.name, }; - // Workaround, Yargs does not play nicely with both --parameter and --no-parameter set. - // Negating a number parameter returns 0, making deliveryDelay an array with [0, ] if (Array.isArray(args.deliveryDelay)) { throw new CommandLineArgsError( `Error: can't use more than a delay setting.` From 9c1ceeda2844df92317e511203673e4bbef0f528 Mon Sep 17 00:00:00 2001 From: Pedro Leal Date: Tue, 5 Mar 2024 13:59:21 +0000 Subject: [PATCH 12/17] Update packages/wrangler/src/queues/cli/commands/create.ts Co-authored-by: MrBBot --- packages/wrangler/src/queues/cli/commands/create.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/wrangler/src/queues/cli/commands/create.ts b/packages/wrangler/src/queues/cli/commands/create.ts index 0df51168db25..7e804c2d3eeb 100644 --- a/packages/wrangler/src/queues/cli/commands/create.ts +++ b/packages/wrangler/src/queues/cli/commands/create.ts @@ -34,7 +34,7 @@ function createBody( if (Array.isArray(args.deliveryDelay)) { throw new CommandLineArgsError( - `Error: can't use more than a delay setting.` + "Cannot specify --delivery-delay multiple times" ); } From c9e6b8aeecde288d51b5559ec350543ece2ac814 Mon Sep 17 00:00:00 2001 From: Pedro Leal Date: Tue, 5 Mar 2024 13:59:27 +0000 Subject: [PATCH 13/17] Update packages/wrangler/src/queues/cli/commands/consumer/add.ts Co-authored-by: MrBBot --- .../wrangler/src/queues/cli/commands/consumer/worker/add.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/wrangler/src/queues/cli/commands/consumer/worker/add.ts b/packages/wrangler/src/queues/cli/commands/consumer/worker/add.ts index d4b43bff2d4e..be5edd2223db 100644 --- a/packages/wrangler/src/queues/cli/commands/consumer/worker/add.ts +++ b/packages/wrangler/src/queues/cli/commands/consumer/worker/add.ts @@ -47,7 +47,7 @@ export function options(yargs: CommonYargsArgv) { "retry-delay": { type: "number", describe: - "How long a retried messages should be delayed for, in seconds. Must be a positive integer", + "How long a retried message should be delayed for, in seconds. Must be a positive integer", number: true, }, }); From e0f68be0b3c22d9c8cc54cd2cf3fd0406b1decbe Mon Sep 17 00:00:00 2001 From: Pedro Leal Date: Tue, 5 Mar 2024 13:59:34 +0000 Subject: [PATCH 14/17] Update packages/wrangler/src/__tests__/queues.test.ts Co-authored-by: MrBBot --- packages/wrangler/src/__tests__/queues.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/wrangler/src/__tests__/queues.test.ts b/packages/wrangler/src/__tests__/queues.test.ts index 3fa59b89d30b..d0b0d9b583b4 100644 --- a/packages/wrangler/src/__tests__/queues.test.ts +++ b/packages/wrangler/src/__tests__/queues.test.ts @@ -219,7 +219,7 @@ describe("wrangler", () => { -v, --version Show version number [boolean] Options: - --delivery-delay How long a published messages should be delayed for, in seconds. Must be a positive integer [number]" + --delivery-delay How long a published message should be delayed for, in seconds. Must be a positive integer [number]" `); }); From 2283f441d87b11fc0bde72d5708334e9fa8a6ed1 Mon Sep 17 00:00:00 2001 From: Pedro Leal Date: Tue, 5 Mar 2024 13:59:53 +0000 Subject: [PATCH 15/17] Update .changeset/warm-seahorses-trade.md Co-authored-by: MrBBot --- .changeset/warm-seahorses-trade.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.changeset/warm-seahorses-trade.md b/.changeset/warm-seahorses-trade.md index 2e4297858f30..20d14b40a65b 100644 --- a/.changeset/warm-seahorses-trade.md +++ b/.changeset/warm-seahorses-trade.md @@ -2,4 +2,4 @@ "wrangler": minor --- -Added support for queue delivery controls on Queue create and Consumer create. +feature: add support for queue delivery controls on `wrangler queues create` and `wrangler queues consumer add` From 49262222102a783426908bc36fdf4fcf9c176ed0 Mon Sep 17 00:00:00 2001 From: Pedro Leal Date: Wed, 6 Mar 2024 17:59:47 +0000 Subject: [PATCH 16/17] Tests passing --- packages/wrangler/src/__tests__/queues.test.ts | 6 +++--- .../wrangler/src/queues/cli/commands/consumer/worker/add.ts | 2 +- packages/wrangler/src/queues/cli/commands/create.ts | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/wrangler/src/__tests__/queues.test.ts b/packages/wrangler/src/__tests__/queues.test.ts index d0b0d9b583b4..ddaf14619b16 100644 --- a/packages/wrangler/src/__tests__/queues.test.ts +++ b/packages/wrangler/src/__tests__/queues.test.ts @@ -290,7 +290,7 @@ describe("wrangler", () => { "queues create testQueue --delivery-delay=5 --delivery-delay=10" ) ).rejects.toThrowErrorMatchingInlineSnapshot( - `"Error: can't use more than a delay setting."` + `"Cannot specify --delivery-delay multiple times"` ); expect(requests.count).toEqual(0); @@ -430,7 +430,7 @@ describe("wrangler", () => { --message-retries Maximum number of retries for each message [number] --dead-letter-queue Queue to send messages that failed to be consumed [string] --max-concurrency The maximum number of concurrent consumer Worker invocations. Must be a positive integer [number] - --retry-delay How long a retried messages should be delayed for, in seconds. Must be a positive integer [number]" + --retry-delay How long a retried message should be delayed for, in seconds. Must be a positive integer [number]" `); }); @@ -499,7 +499,7 @@ describe("wrangler", () => { "queues consumer add testQueue testScript --env myEnv --batch-size 20 --batch-timeout 10 --message-retries 3 --max-concurrency 3 --dead-letter-queue myDLQ --retry-delay=5 --retry-delay=10" ) ).rejects.toThrowErrorMatchingInlineSnapshot( - `"Error: can't use more than a delay setting."` + `"Cannot specify --retry-delay multiple times"` ); expect(requests.count).toEqual(0); diff --git a/packages/wrangler/src/queues/cli/commands/consumer/worker/add.ts b/packages/wrangler/src/queues/cli/commands/consumer/worker/add.ts index be5edd2223db..a9cb4ffb0e35 100644 --- a/packages/wrangler/src/queues/cli/commands/consumer/worker/add.ts +++ b/packages/wrangler/src/queues/cli/commands/consumer/worker/add.ts @@ -73,7 +73,7 @@ function createBody( if (Array.isArray(args.retryDelay)) { throw new CommandLineArgsError( - `Error: can't use more than a delay setting.` + `Cannot specify --retry-delay multiple times` ); } diff --git a/packages/wrangler/src/queues/cli/commands/create.ts b/packages/wrangler/src/queues/cli/commands/create.ts index 7e804c2d3eeb..e897fab85154 100644 --- a/packages/wrangler/src/queues/cli/commands/create.ts +++ b/packages/wrangler/src/queues/cli/commands/create.ts @@ -20,7 +20,7 @@ export function options(yargs: CommonYargsArgv) { "delivery-delay": { type: "number", describe: - "How long a published messages should be delayed for, in seconds. Must be a positive integer", + "How long a published message should be delayed for, in seconds. Must be a positive integer", }, }); } From fa222f28b96d2966545bf9348a986a2144e68159 Mon Sep 17 00:00:00 2001 From: Pedro Leal Date: Thu, 21 Mar 2024 16:28:42 +0000 Subject: [PATCH 17/17] Updated commands to support HTTP Pull consumers --- .changeset/warm-seahorses-trade.md | 2 +- .../wrangler/src/__tests__/queues.test.ts | 16 ++--- .../cli/commands/consumer/http-pull/add.ts | 7 ++ .../cli/commands/consumer/worker/add.ts | 61 +++++++---------- .../src/queues/cli/commands/create.ts | 10 +-- packages/wrangler/src/queues/client.ts | 66 ++++++++++++++++++- 6 files changed, 107 insertions(+), 55 deletions(-) diff --git a/.changeset/warm-seahorses-trade.md b/.changeset/warm-seahorses-trade.md index 20d14b40a65b..7298aa003199 100644 --- a/.changeset/warm-seahorses-trade.md +++ b/.changeset/warm-seahorses-trade.md @@ -2,4 +2,4 @@ "wrangler": minor --- -feature: add support for queue delivery controls on `wrangler queues create` and `wrangler queues consumer add` +feature: add support for queue delivery controls on `wrangler queues create` diff --git a/packages/wrangler/src/__tests__/queues.test.ts b/packages/wrangler/src/__tests__/queues.test.ts index ddaf14619b16..9ca0a8e7e38c 100644 --- a/packages/wrangler/src/__tests__/queues.test.ts +++ b/packages/wrangler/src/__tests__/queues.test.ts @@ -219,7 +219,7 @@ describe("wrangler", () => { -v, --version Show version number [boolean] Options: - --delivery-delay How long a published message should be delayed for, in seconds. Must be a positive integer [number]" + --delivery-delay-secs How long a published message should be delayed for, in seconds. Must be a positive integer [number]" `); }); @@ -274,7 +274,7 @@ describe("wrangler", () => { it("should send queue settings with delivery delay", async () => { const requests = mockCreateRequest("testQueue", { delivery_delay: 10 }); - await runWrangler("queues create testQueue --delivery-delay=10"); + await runWrangler("queues create testQueue --delivery-delay-secs=10"); expect(std.out).toMatchInlineSnapshot(` "Creating queue testQueue. Created queue testQueue." @@ -287,10 +287,10 @@ describe("wrangler", () => { await expect( runWrangler( - "queues create testQueue --delivery-delay=5 --delivery-delay=10" + "queues create testQueue --delivery-delay-secs=5 --delivery-delay-secs=10" ) ).rejects.toThrowErrorMatchingInlineSnapshot( - `"Cannot specify --delivery-delay multiple times"` + `"Cannot specify --delivery-delay-secs multiple times"` ); expect(requests.count).toEqual(0); @@ -430,7 +430,7 @@ describe("wrangler", () => { --message-retries Maximum number of retries for each message [number] --dead-letter-queue Queue to send messages that failed to be consumed [string] --max-concurrency The maximum number of concurrent consumer Worker invocations. Must be a positive integer [number] - --retry-delay How long a retried message should be delayed for, in seconds. Must be a positive integer [number]" + --retry-delay-secs The number of seconds to wait before retrying a message [number]" `); }); @@ -471,7 +471,7 @@ describe("wrangler", () => { mockPostRequest("testQueue", expectedBody); await runWrangler( - "queues consumer add testQueue testScript --env myEnv --batch-size 20 --batch-timeout 10 --message-retries 3 --max-concurrency 3 --dead-letter-queue myDLQ --retry-delay=10" + "queues consumer add testQueue testScript --env myEnv --batch-size 20 --batch-timeout 10 --message-retries 3 --max-concurrency 3 --dead-letter-queue myDLQ --retry-delay-secs=10" ); expect(std.out).toMatchInlineSnapshot(` "Adding consumer to queue testQueue. @@ -496,10 +496,10 @@ describe("wrangler", () => { await expect( runWrangler( - "queues consumer add testQueue testScript --env myEnv --batch-size 20 --batch-timeout 10 --message-retries 3 --max-concurrency 3 --dead-letter-queue myDLQ --retry-delay=5 --retry-delay=10" + "queues consumer add testQueue testScript --env myEnv --batch-size 20 --batch-timeout 10 --message-retries 3 --max-concurrency 3 --dead-letter-queue myDLQ --retry-delay-secs=5 --retry-delay-secs=10" ) ).rejects.toThrowErrorMatchingInlineSnapshot( - `"Cannot specify --retry-delay multiple times"` + `"Cannot specify --retry-delay-secs multiple times"` ); expect(requests.count).toEqual(0); diff --git a/packages/wrangler/src/queues/cli/commands/consumer/http-pull/add.ts b/packages/wrangler/src/queues/cli/commands/consumer/http-pull/add.ts index 9e0d0601a27d..8a80d4e53d6e 100644 --- a/packages/wrangler/src/queues/cli/commands/consumer/http-pull/add.ts +++ b/packages/wrangler/src/queues/cli/commands/consumer/http-pull/add.ts @@ -1,4 +1,5 @@ import { readConfig } from "../../../../../config"; +import { CommandLineArgsError } from "../../../../../index"; import { logger } from "../../../../../logger"; import { postTypedConsumer } from "../../../../client"; import type { @@ -44,6 +45,12 @@ export async function handler( ) { const config = readConfig(args.config, args); + if (Array.isArray(args.retryDelaySecs)) { + throw new CommandLineArgsError( + `Cannot specify --retry-delay-secs multiple times` + ); + } + const postTypedConsumerBody: PostTypedConsumerBody = { type: "http_pull", settings: { diff --git a/packages/wrangler/src/queues/cli/commands/consumer/worker/add.ts b/packages/wrangler/src/queues/cli/commands/consumer/worker/add.ts index a9cb4ffb0e35..5c02e86314dc 100644 --- a/packages/wrangler/src/queues/cli/commands/consumer/worker/add.ts +++ b/packages/wrangler/src/queues/cli/commands/consumer/worker/add.ts @@ -1,13 +1,12 @@ -import { readConfig } from "../../../../config"; -import { CommandLineArgsError } from "../../../../index"; -import { logger } from "../../../../logger"; -import { postConsumer } from "../../../client"; -import { handleFetchError } from "../../../utils"; +import { readConfig } from "../../../../../config"; +import { CommandLineArgsError } from "../../../../../index"; +import { logger } from "../../../../../logger"; +import { postConsumer } from "../../../../client"; import type { CommonYargsArgv, StrictYargsOptionsToInterface, -} from "../../../../yargs-types"; -import type { PostConsumerBody } from "../../../client"; +} from "../../../../../yargs-types"; +import type { PostConsumerBody } from "../../../../client"; export function options(yargs: CommonYargsArgv) { return yargs @@ -44,18 +43,24 @@ export function options(yargs: CommonYargsArgv) { describe: "The maximum number of concurrent consumer Worker invocations. Must be a positive integer", }, - "retry-delay": { + "retry-delay-secs": { type: "number", - describe: - "How long a retried message should be delayed for, in seconds. Must be a positive integer", - number: true, + describe: "The number of seconds to wait before retrying a message", }, }); } -function createBody( +export async function handler( args: StrictYargsOptionsToInterface -): PostConsumerBody { +) { + const config = readConfig(args.config, args); + + if (Array.isArray(args.retryDelaySecs)) { + throw new CommandLineArgsError( + `Cannot specify --retry-delay-secs multiple times` + ); + } + const body: PostConsumerBody = { script_name: args.scriptName, // TODO(soon) is this still the correct usage of the environment? @@ -67,34 +72,12 @@ function createBody( ? 1000 * args.batchTimeout : undefined, max_concurrency: args.maxConcurrency, + retry_delay: args.retryDelaySecs, }, dead_letter_queue: args.deadLetterQueue, }; - if (Array.isArray(args.retryDelay)) { - throw new CommandLineArgsError( - `Cannot specify --retry-delay multiple times` - ); - } - - if (args.retryDelay != undefined) { - body.settings.retry_delay = args.retryDelay; - } - - return body; -} - -export async function handler( - args: StrictYargsOptionsToInterface -) { - const config = readConfig(args.config, args); - const body = createBody(args); - - try { - logger.log(`Adding consumer to queue ${args.queueName}.`); - await postConsumer(config, args.queueName, body); - logger.log(`Added consumer to queue ${args.queueName}.`); - } catch (e) { - handleFetchError(e as { code?: number }); - } + logger.log(`Adding consumer to queue ${args.queueName}.`); + await postConsumer(config, args.queueName, body); + logger.log(`Added consumer to queue ${args.queueName}.`); } diff --git a/packages/wrangler/src/queues/cli/commands/create.ts b/packages/wrangler/src/queues/cli/commands/create.ts index e897fab85154..c51da73bdf96 100644 --- a/packages/wrangler/src/queues/cli/commands/create.ts +++ b/packages/wrangler/src/queues/cli/commands/create.ts @@ -17,7 +17,7 @@ export function options(yargs: CommonYargsArgv) { description: "The name of the queue", }) .options({ - "delivery-delay": { + "delivery-delay-secs": { type: "number", describe: "How long a published message should be delayed for, in seconds. Must be a positive integer", @@ -32,15 +32,15 @@ function createBody( queue_name: args.name, }; - if (Array.isArray(args.deliveryDelay)) { + if (Array.isArray(args.deliveryDelaySecs)) { throw new CommandLineArgsError( - "Cannot specify --delivery-delay multiple times" + "Cannot specify --delivery-delay-secs multiple times" ); } - if (args.deliveryDelay != undefined) { + if (args.deliveryDelaySecs != undefined) { body.settings = { - delivery_delay: args.deliveryDelay, + delivery_delay: args.deliveryDelaySecs, }; } diff --git a/packages/wrangler/src/queues/client.ts b/packages/wrangler/src/queues/client.ts index c69ddc369164..3c35dbfcc953 100644 --- a/packages/wrangler/src/queues/client.ts +++ b/packages/wrangler/src/queues/client.ts @@ -1,5 +1,6 @@ import { fetchResult } from "../cfetch"; import { type Config } from "../config"; +import { UserError } from "../errors"; import { requireAuth } from "../user"; export async function createQueue( @@ -19,7 +20,7 @@ export interface CreateQueueBody { } export interface QueueSettings { - delivery_delay?: number; + delivery_delay: number; } export interface ScriptReference { @@ -46,7 +47,7 @@ export interface QueueResponse { producers_total_count: number; consumers: Consumer[]; consumers_total_count: number; - settings: QueueSettings; + settings?: QueueSettings; } export async function deleteQueue( @@ -102,6 +103,50 @@ export async function postConsumer( ); } +export async function postTypedConsumer( + config: Config, + queueName: string, + body: PostTypedConsumerBody +): Promise { + const accountId = await requireAuth(config); + const queue = await getQueue(config, queueName); + return fetchResult( + `/accounts/${accountId}/queues/${queue.queue_id}/consumers`, + { + method: "POST", + body: JSON.stringify(body), + } + ); +} + +export async function putTypedConsumer( + config: Config, + queueId: string, + consumerId: string, + body: PostTypedConsumerBody +): Promise { + const accountId = await requireAuth(config); + + return fetchResult( + `/accounts/${accountId}/queues/${queueId}/consumers/${consumerId}`, + { + method: "PUT", + body: JSON.stringify(body), + } + ); +} + +export interface TypedConsumerResponse extends Consumer { + queue_name: string; + created_on: string; +} + +export interface PostTypedConsumerBody extends PutConsumerBody { + type: string; + script_name?: string; + environment_name?: string; +} + export interface PutConsumerBody { settings: ConsumerSettings; dead_letter_queue?: string; @@ -117,6 +162,7 @@ export interface ConsumerSettings { max_retries?: number; max_wait_time_ms?: number; max_concurrency?: number | null; + visibility_timeout_ms?: number; retry_delay?: number; } @@ -128,6 +174,22 @@ export interface ConsumerResponse extends PostConsumerBody { dead_letter_queue?: string; } +export async function deletePullConsumer( + config: Config, + queueName: string +): Promise { + const accountId = await requireAuth(config); + const queue = await getQueue(config, queueName); + const consumer = queue.consumers[0]; + if (consumer?.type !== "http_pull") { + throw new UserError(`No http_pull consumer exists for queue ${queueName}`); + } + const resource = `/accounts/${accountId}/queues/${queue.queue_id}/consumers/${consumer.consumer_id}`; + return fetchResult(resource, { + method: "DELETE", + }); +} + export async function deleteConsumer( config: Config, queueName: string,