From 335ef6bb74825086f31aad461989430be978b3be Mon Sep 17 00:00:00 2001 From: James Ritchie Date: Wed, 30 Apr 2025 15:08:20 +0100 Subject: [PATCH 1/8] Combines the Running and Concurrency limit cols into 1 --- .../route.tsx | 20 +++++++------------ 1 file changed, 7 insertions(+), 13 deletions(-) diff --git a/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.queues/route.tsx b/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.queues/route.tsx index c48c45560b..391f301110 100644 --- a/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.queues/route.tsx +++ b/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.queues/route.tsx @@ -294,7 +294,7 @@ export default function Page() { Name Queued - Running + Running/limit Release on waitpoint - Concurrency limit Pause/resume @@ -378,7 +377,12 @@ export default function Page() { alignment="right" className={queue.paused ? "opacity-50" : undefined} > - {queue.running} + {queue.running}/ + {queue.concurrencyLimit ?? ( + + {environment.concurrencyLimit} (Max) + + )} {queue.releaseConcurrencyOnWaitpoint ? "Yes" : "No"} - - {queue.concurrencyLimit ?? ( - - Max ({environment.concurrencyLimit}) - - )} - } From 56f4c2392e448ca83325ca1efa70a53d63690b6a Mon Sep 17 00:00:00 2001 From: James Ritchie Date: Wed, 30 Apr 2025 15:14:34 +0100 Subject: [PATCH 2/8] Display a badge when a queue is at the concurrency limit --- .../route.tsx | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.queues/route.tsx b/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.queues/route.tsx index 391f301110..d466239665 100644 --- a/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.queues/route.tsx +++ b/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.queues/route.tsx @@ -365,6 +365,11 @@ export default function Page() { Paused ) : null} + {queue.running === queue.concurrencyLimit ? ( + + At concurrency limit + + ) : null} {env.paused - ? `Resume processing runs in ${environmentFullTitle(env)}.` - : `Pause processing runs in ${environmentFullTitle(env)}.`} + ? `Resume processing runs in ${environmentFullTitle(env)}` + : `Pause processing runs in ${environmentFullTitle(env)}`} From dfc5c594f8cd30fbf85fc34468ec9e8f040c86b5 Mon Sep 17 00:00:00 2001 From: James Ritchie Date: Wed, 30 Apr 2025 15:18:53 +0100 Subject: [PATCH 3/8] Colors the Running/Limit column text amber if the concurrency limit is hit --- .../route.tsx | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.queues/route.tsx b/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.queues/route.tsx index d466239665..1f73e37587 100644 --- a/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.queues/route.tsx +++ b/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.queues/route.tsx @@ -380,11 +380,19 @@ export default function Page() { {queue.running}/ {queue.concurrencyLimit ?? ( - + {environment.concurrencyLimit} (Max) )} From 92835f1bbc95085920d583d00beefccf055bfad5 Mon Sep 17 00:00:00 2001 From: James Ritchie Date: Wed, 30 Apr 2025 15:36:25 +0100 Subject: [PATCH 4/8] =?UTF-8?q?Turns=20the=20=E2=80=9CRunning=E2=80=9D=20b?= =?UTF-8?q?ig=20number=20amber=20and=20shows=20=E2=80=9CAt=20concurrency?= =?UTF-8?q?=20limit=E2=80=9D=20text?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../route.tsx | 27 ++++++++++++++----- 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.queues/route.tsx b/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.queues/route.tsx index 1f73e37587..12425c1ea5 100644 --- a/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.queues/route.tsx +++ b/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.queues/route.tsx @@ -245,13 +245,28 @@ export default function Page() { suffix={env.paused && environment.queued > 0 ? "paused" : undefined} animate accessory={} - valueClassName={env.paused ? "text-amber-500" : undefined} + valueClassName={env.paused ? "text-warning" : undefined} + /> + - {queue.running}/ @@ -390,7 +405,7 @@ export default function Page() { {environment.concurrencyLimit} (Max) @@ -493,7 +508,7 @@ function EnvironmentPauseResumeButton({ type="button" variant="secondary/small" LeadingIcon={env.paused ? PlayIcon : PauseIcon} - leadingIconClassName={env.paused ? "text-success" : "text-amber-500"} + leadingIconClassName={env.paused ? "text-success" : "text-warning"} > {env.paused ? "Resume..." : "Pause environment..."} @@ -572,7 +587,7 @@ function QueuePauseResumeButton({ type="button" variant="tertiary/small" LeadingIcon={queue.paused ? PlayIcon : PauseIcon} - leadingIconClassName={queue.paused ? "text-success" : "text-amber-500"} + leadingIconClassName={queue.paused ? "text-success" : "text-warning"} > {queue.paused ? "Resume..." : "Pause..."} From b25c0648e0888e37db998305f009eba8e3d026e8 Mon Sep 17 00:00:00 2001 From: James Ritchie Date: Wed, 30 Apr 2025 16:49:42 +0100 Subject: [PATCH 5/8] BigNumber now handles big values using formatNumber and formatNumberCompact Also includes some responsive improvements to make sure things wrap when it gets tight --- .../app/components/metrics/BigNumber.tsx | 33 +++++++++++++++---- .../components/primitives/AnimatedNumber.tsx | 2 +- 2 files changed, 28 insertions(+), 7 deletions(-) diff --git a/apps/webapp/app/components/metrics/BigNumber.tsx b/apps/webapp/app/components/metrics/BigNumber.tsx index 2097ba928b..d5482fd529 100644 --- a/apps/webapp/app/components/metrics/BigNumber.tsx +++ b/apps/webapp/app/components/metrics/BigNumber.tsx @@ -1,7 +1,10 @@ import { type ReactNode } from "react"; import { AnimatedNumber } from "../primitives/AnimatedNumber"; import { Spinner } from "../primitives/Spinner"; +import { SimpleTooltip } from "../primitives/Tooltip"; import { cn } from "~/utils/cn"; +import { formatNumber, formatNumberCompact } from "~/utils/numberFormatter"; +import { Header3 } from "../primitives/Headers"; interface BigNumberProps { title: ReactNode; @@ -13,6 +16,7 @@ interface BigNumberProps { accessory?: ReactNode; suffix?: string; suffixClassName?: string; + compactThreshold?: number; } export function BigNumber({ @@ -25,25 +29,42 @@ export function BigNumber({ accessory, animate = false, loading = false, + compactThreshold = 100000, }: BigNumberProps) { const v = value ?? defaultValue; + + const formatValue = (num: number) => { + return num >= compactThreshold ? formatNumberCompact(num) : formatNumber(num); + }; + + const shouldCompact = v !== undefined && v >= compactThreshold; + return ( -
-
-
{title}
+
+
+ {title} {accessory &&
{accessory}
}
{loading ? ( ) : v !== undefined ? ( -
- {animate ? : v} +
+ {shouldCompact ? ( + : formatValue(v)} + content={formatNumber(v)} + /> + ) : animate ? ( + + ) : ( + formatValue(v) + )} {suffix &&
{suffix}
}
) : ( diff --git a/apps/webapp/app/components/primitives/AnimatedNumber.tsx b/apps/webapp/app/components/primitives/AnimatedNumber.tsx index a585670502..f2f309a526 100644 --- a/apps/webapp/app/components/primitives/AnimatedNumber.tsx +++ b/apps/webapp/app/components/primitives/AnimatedNumber.tsx @@ -1,4 +1,4 @@ -import { motion, useSpring, useTransform, useMotionValue, animate } from "framer-motion"; +import { animate, motion, useMotionValue, useTransform } from "framer-motion"; import { useEffect } from "react"; export function AnimatedNumber({ value }: { value: number }) { From 7daa774313c5853173f2980c4b49d14b7be2f157 Mon Sep 17 00:00:00 2001 From: James Ritchie Date: Thu, 1 May 2025 15:40:41 +0100 Subject: [PATCH 6/8] Adds a new col for showing how the queue is limited --- .../route.tsx | 198 +++++++++++------- 1 file changed, 122 insertions(+), 76 deletions(-) diff --git a/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.queues/route.tsx b/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.queues/route.tsx index 12425c1ea5..a6c2a2f8cb 100644 --- a/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.queues/route.tsx +++ b/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.queues/route.tsx @@ -61,6 +61,7 @@ import { docsPath, EnvironmentParamSchema, v3BillingPath } from "~/utils/pathBui import { PauseEnvironmentService } from "~/v3/services/pauseEnvironment.server"; import { PauseQueueService } from "~/v3/services/pauseQueue.server"; import { useCurrentPlan } from "../_app.orgs.$organizationSlug/route"; +import { Header3 } from "~/components/primitives/Headers"; const SearchParamsSchema = z.object({ page: z.coerce.number().min(1).default(1), @@ -310,6 +311,36 @@ export default function Page() { Name Queued Running/limit + +
+ Environment + + This queue is limited by your environment's concurrency limit of{" "} + {environment.concurrencyLimit}. + +
+
+ User + + This queue is limited by a concurrency limit set in your code. + +
+
+ } + > + Limited by + {queues.length > 0 ? ( - queues.map((queue) => ( - - - - {queue.type === "task" ? ( - - } - content={`This queue was automatically created from your "${queue.name}" task`} - /> - ) : ( - - } - content={`This is a custom queue you added in your code.`} - /> - )} - - {queue.name} + queues.map((queue) => { + const limit = queue.concurrencyLimit ?? environment.concurrencyLimit; + const isAtLimit = queue.running === limit; + return ( + + + + {queue.type === "task" ? ( + + } + content={`This queue was automatically created from your "${queue.name}" task`} + /> + ) : ( + + } + content={`This is a custom queue you added in your code.`} + /> + )} + + {queue.name} + + {queue.paused ? ( + + Paused + + ) : null} + {isAtLimit ? ( + + At concurrency limit + + ) : null} - {queue.paused ? ( - - Paused - - ) : null} - {queue.running === queue.concurrencyLimit ? ( - - At concurrency limit - - ) : null} - - - - {queue.queued} - - - {queue.running}/ - {queue.concurrencyLimit ?? ( + + + {queue.queued} + + + {queue.running}/ - {environment.concurrencyLimit} (Max) + {limit} - )} - - - {queue.releaseConcurrencyOnWaitpoint ? "Yes" : "No"} - - } - hiddenButtons={!queue.paused && } - /> - - )) + + + {queue.concurrencyLimit ? "User" : "Environment"} + + + {queue.releaseConcurrencyOnWaitpoint ? "Yes" : "No"} + + + } + hiddenButtons={ + !queue.paused && + } + /> + + ); + }) ) : ( From 0921c5c27f51f708cd3d0ce9199fe2fe255ad876 Mon Sep 17 00:00:00 2001 From: James Ritchie Date: Thu, 1 May 2025 16:15:17 +0100 Subject: [PATCH 7/8] Reinstates a threshold for making very big numbers compact --- .../app/components/metrics/BigNumber.tsx | 19 ++++++++----------- .../route.tsx | 2 ++ 2 files changed, 10 insertions(+), 11 deletions(-) diff --git a/apps/webapp/app/components/metrics/BigNumber.tsx b/apps/webapp/app/components/metrics/BigNumber.tsx index d5482fd529..7c4441be34 100644 --- a/apps/webapp/app/components/metrics/BigNumber.tsx +++ b/apps/webapp/app/components/metrics/BigNumber.tsx @@ -1,10 +1,10 @@ import { type ReactNode } from "react"; -import { AnimatedNumber } from "../primitives/AnimatedNumber"; -import { Spinner } from "../primitives/Spinner"; -import { SimpleTooltip } from "../primitives/Tooltip"; import { cn } from "~/utils/cn"; import { formatNumber, formatNumberCompact } from "~/utils/numberFormatter"; import { Header3 } from "../primitives/Headers"; +import { Spinner } from "../primitives/Spinner"; +import { SimpleTooltip } from "../primitives/Tooltip"; +import { AnimatedNumber } from "../primitives/AnimatedNumber"; interface BigNumberProps { title: ReactNode; @@ -29,15 +29,12 @@ export function BigNumber({ accessory, animate = false, loading = false, - compactThreshold = 100000, + compactThreshold, }: BigNumberProps) { const v = value ?? defaultValue; - const formatValue = (num: number) => { - return num >= compactThreshold ? formatNumberCompact(num) : formatNumber(num); - }; - - const shouldCompact = v !== undefined && v >= compactThreshold; + const shouldCompact = + typeof compactThreshold === "number" && v !== undefined && v >= compactThreshold; return (
@@ -57,13 +54,13 @@ export function BigNumber({
{shouldCompact ? ( : formatValue(v)} + button={animate ? : formatNumberCompact(v)} content={formatNumber(v)} /> ) : animate ? ( ) : ( - formatValue(v) + formatNumber(v) )} {suffix &&
{suffix}
}
diff --git a/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.queues/route.tsx b/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.queues/route.tsx index a6c2a2f8cb..9eed9be9b1 100644 --- a/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.queues/route.tsx +++ b/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.queues/route.tsx @@ -247,6 +247,7 @@ export default function Page() { animate accessory={} valueClassName={env.paused ? "text-warning" : undefined} + compactThreshold={1000000} /> Date: Thu, 1 May 2025 17:24:12 +0100 Subject: [PATCH 8/8] Added border to make the search bar not float --- .../route.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.queues/route.tsx b/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.queues/route.tsx index 4297944d3b..c9820c726a 100644 --- a/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.queues/route.tsx +++ b/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.queues/route.tsx @@ -773,7 +773,7 @@ export function QueueFilters() { const search = searchParams.get("query") ?? ""; return ( -
+