Skip to content

Commit

Permalink
feat(FR-555): Improve the auto-scaling rule editor interface and list (
Browse files Browse the repository at this point in the history
…#3202)

Resolves #3201 (FR-555)
### TL;DR

> For test, please pull this lablup/backend.ai#3757 to your test server

Redesigned the auto-scaling rule editor interface to improve usability and add separate controls for scale up/down operations.

### What changed?

- Added distinct scale up/down options instead of combining them
- Simplified metric selection with autocomplete and predefined options
- Consolidated condition inputs (metric, comparator, threshold) into a single row
- Removed redundant min/max replica fields based on scaling direction
- Added tooltips and improved validation logic
- Updated translations for all supported languages with new UI strings

### How to test?

1. Open the endpoint detail page
2. Click to add a new auto-scaling rule
3. Verify the new UI with separate scale up/down options
4. Test metric name autocomplete functionality
5. Confirm min/max replicas show correctly based on scale direction
6. Validate form submissions work for both scale up and down scenarios

### Why make this change?

The previous interface combined scale up/down operations which made it confusing for users to configure rules correctly. This redesign separates the concerns and provides a more intuitive workflow while reducing potential configuration errors through better validation and clearer UI elements.
  • Loading branch information
agatha197 committed Feb 19, 2025
1 parent ed53e3c commit a777826
Show file tree
Hide file tree
Showing 23 changed files with 421 additions and 200 deletions.
363 changes: 226 additions & 137 deletions react/src/components/AutoScalingRuleEditorModal.tsx

Large diffs are not rendered by default.

111 changes: 69 additions & 42 deletions react/src/pages/EndpointDetailPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import ImageMetaIcon from '../components/ImageMetaIcon';
import InferenceSessionErrorModal from '../components/InferenceSessionErrorModal';
import ResourceNumber from '../components/ResourceNumber';
import SessionDetailDrawer from '../components/SessionDetailDrawer';
import UnmountModalAfterClose from '../components/UnmountModalAfterClose';
import VFolderLazyView from '../components/VFolderLazyView';
import { AutoScalingRuleEditorModalFragment$key } from '../components/__generated__/AutoScalingRuleEditorModalFragment.graphql';
import { InferenceSessionErrorModalFragment$key } from '../components/__generated__/InferenceSessionErrorModalFragment.graphql';
Expand Down Expand Up @@ -63,7 +64,11 @@ import { DescriptionsItemType } from 'antd/es/descriptions';
import graphql from 'babel-plugin-relay/macro';
import { default as dayjs } from 'dayjs';
import _ from 'lodash';
import { BotMessageSquareIcon } from 'lucide-react';
import {
BotMessageSquareIcon,
CircleArrowDownIcon,
CircleArrowUpIcon,
} from 'lucide-react';
import React, { Suspense, useState, useTransition } from 'react';
import { useTranslation } from 'react-i18next';
import { useLazyLoadQuery, useMutation } from 'react-relay';
Expand Down Expand Up @@ -634,21 +639,33 @@ const EndpointDetailPage: React.FC<EndpointDetailPageProps> = () => {
rowKey={'id'}
columns={[
{
title: '#',
title: t('autoScalingRule.ScalingType'),
fixed: 'left',
render: (id, record, index) => {
++index;
return index;
},
render: (text, row) =>
(row?.step_size || 0) > 0 ? 'Up' : 'Down',
},
{
title: t('autoScalingRule.MetricSource'),
dataIndex: 'metric_source',
// render: (text, row) => <Tag>{row?.metric_source}</Tag>,
},
{
title: t('autoScalingRule.MetricName'),
title: t('autoScalingRule.Condition'),
dataIndex: 'metric_name',
fixed: 'left',
render: (text, row) => (
<Typography.Text ellipsis copyable style={{ width: 150 }}>
{row?.metric_name}
</Typography.Text>
<Flex gap={'xs'}>
<Tag>{row?.metric_name}</Tag>
{row?.comparator ? (
<Tooltip title={row.comparator}>
{/* @ts-ignore */}
{COMPARATOR_LABELS[row.comparator]}
</Tooltip>
) : (
'-'
)}
{row?.threshold}
</Flex>
),
},
{
Expand Down Expand Up @@ -769,32 +786,40 @@ const EndpointDetailPage: React.FC<EndpointDetailPageProps> = () => {
</Flex>
),
},
{
title: t('autoScalingRule.MetricSource'),
dataIndex: 'metric_source',
render: (text, row) => <Tag>{row?.metric_source}</Tag>,
},
{
title: t('autoScalingRule.Comparator'),
dataIndex: 'comparator',
render: (text, row) => (
// @ts-ignore
<Tooltip title={text}>{COMPARATOR_LABELS[text]}</Tooltip>
),
},
{
title: t('autoScalingRule.Threshold'),
render: (text, row) => <span>{row?.threshold}</span>,
},

{
title: t('autoScalingRule.StepSize'),
dataIndex: 'step_size',
render: (text, row) => {
if (row?.step_size) {
return (
<Flex gap={'xs'}>
<Typography.Text>
{row?.step_size > 0 ? (
<CircleArrowUpIcon />
) : (
<CircleArrowDownIcon />
)}
</Typography.Text>
<Typography.Text>
{Math.abs(row?.step_size)}
</Typography.Text>
</Flex>
);
} else {
return '-';
}
},
},
{
title: t('autoScalingRule.MIN/MAXReplicas'),
render: (text, row) => (
<span>
Min: {row?.min_replicas} / Max: {row?.max_replicas}
{row?.step_size
? row?.step_size > 0
? `Max: ${row?.max_replicas}`
: `Min: ${row?.min_replicas}`
: '-'}
</span>
),
},
Expand Down Expand Up @@ -1064,20 +1089,22 @@ const EndpointDetailPage: React.FC<EndpointDetailPageProps> = () => {
}}
/>
{isSupportAutoScalingRule && (
<AutoScalingRuleEditorModal
open={isOpenAutoScalingRuleModal}
endpoint_id={endpoint?.endpoint_id as string}
autoScalingRuleFrgmt={editingAutoScalingRule}
onRequestClose={(success) => {
setIsOpenAutoScalingRuleModal(!isOpenAutoScalingRuleModal);
setEditingAutoScalingRule(null);
if (success) {
startRefetchTransition(() => {
updateFetchKey();
});
}
}}
/>
<UnmountModalAfterClose>
<AutoScalingRuleEditorModal
open={isOpenAutoScalingRuleModal}
endpoint_id={endpoint?.endpoint_id as string}
autoScalingRuleFrgmt={editingAutoScalingRule}
onRequestClose={(success) => {
setIsOpenAutoScalingRuleModal(!isOpenAutoScalingRuleModal);
setEditingAutoScalingRule(null);
if (success) {
startRefetchTransition(() => {
updateFetchKey();
});
}
}}
/>
</UnmountModalAfterClose>
)}
<SessionDetailDrawer
open={!selectedSessionId}
Expand Down
7 changes: 6 additions & 1 deletion resources/i18n/de.json
Original file line number Diff line number Diff line change
Expand Up @@ -1785,7 +1785,12 @@
"MetricSource": "Metrische Quelle",
"MIN/MAXReplicas": "Min / Max Replikas",
"LastTriggered": "Zuletzt ausgelöst",
"CreatedAt": "Zeit erstellt"
"CreatedAt": "Zeit erstellt",
"ConditionTooltip": "Sie können jede von der Laufzeitumgebung unterstützte Metrik frei eingeben.\nZum Beispiel: \"cuda_mem\", \"cuda_util\"",
"ScalingType": "Typ",
"ScaleUp": "Hochskalieren",
"ScaleDown": "Verkleinern",
"Condition": "Zustand"
},
"kernel": {
"KernelId": "Kernel ID",
Expand Down
7 changes: 6 additions & 1 deletion resources/i18n/el.json
Original file line number Diff line number Diff line change
Expand Up @@ -1785,7 +1785,12 @@
"MetricSource": "Μετρική πηγή",
"MIN/MAXReplicas": "Min / Max Replicas",
"LastTriggered": "Τελευταία ενεργοποιημένη",
"CreatedAt": "Δημιουργήθηκε ώρα"
"CreatedAt": "Δημιουργήθηκε ώρα",
"ConditionTooltip": "Μπορείτε να εισαγάγετε ελεύθερα οποιαδήποτε μετρική που υποστηρίζεται από το περιβάλλον εκτέλεσης.\nΓια παράδειγμα: \"cuda_mem\", \"cuda_util\".",
"ScalingType": "Τύπος",
"ScaleUp": "Κλιμάκωση",
"ScaleDown": "Κλιμάκωση προς τα κάτω",
"Condition": "Κατάσταση"
},
"kernel": {
"KernelId": "Αναγνωριστικό πυρήνα",
Expand Down
7 changes: 6 additions & 1 deletion resources/i18n/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -1791,7 +1791,12 @@
"StepSize": "Step Size",
"MIN/MAXReplicas": "Min / MAX Replicas",
"LastTriggered": "Last Triggered",
"CreatedAt": "Created At"
"CreatedAt": "Created At",
"ScaleUp": "Scale Up",
"ScaleDown": "Scale Down",
"Condition": "Condition",
"ConditionTooltip": "You can freely input any metric supported by the runtime environment.\nFor example: \"cuda_mem\", \"cuda_util\"",
"ScalingType": "Type"
},
"kernel": {
"KernelId": "Kernel ID",
Expand Down
7 changes: 6 additions & 1 deletion resources/i18n/es.json
Original file line number Diff line number Diff line change
Expand Up @@ -1785,7 +1785,12 @@
"MetricSource": "Fuente métrica",
"MIN/MAXReplicas": "Réplicas min / max",
"LastTriggered": "Última activación",
"CreatedAt": "Tiempo creado"
"CreatedAt": "Tiempo creado",
"ConditionTooltip": "Puede introducir libremente cualquier métrica admitida por el entorno de ejecución.\nPor ejemplo: \"cuda_mem\", \"cuda_util\"",
"ScalingType": "Tipo",
"ScaleUp": "Ampliar",
"ScaleDown": "Reducción de escala",
"Condition": "Condición"
},
"kernel": {
"KernelId": "ID de núcleo",
Expand Down
7 changes: 6 additions & 1 deletion resources/i18n/fi.json
Original file line number Diff line number Diff line change
Expand Up @@ -1784,7 +1784,12 @@
"MetricSource": "Metrilähde",
"MIN/MAXReplicas": "Min / max -kopiot",
"LastTriggered": "Viimeksi laukaistu",
"CreatedAt": "Luotu aika"
"CreatedAt": "Luotu aika",
"ConditionTooltip": "Voit syöttää vapaasti minkä tahansa ajoympäristön tukeman mittarin.\nEsimerkiksi: \"cuda_mem\", \"cuda_util\".",
"ScalingType": "Tyyppi",
"ScaleUp": "Laajentaminen",
"ScaleDown": "Pienennä mittakaavaa",
"Condition": "Kunto"
},
"kernel": {
"KernelId": "Ytimen tunnus",
Expand Down
7 changes: 6 additions & 1 deletion resources/i18n/fr.json
Original file line number Diff line number Diff line change
Expand Up @@ -1785,7 +1785,12 @@
"MetricSource": "Source métrique",
"MIN/MAXReplicas": "Répliques min / max",
"LastTriggered": "Dernière déclenché",
"CreatedAt": "Temps créé"
"CreatedAt": "Temps créé",
"ConditionTooltip": "Vous pouvez saisir librement n'importe quelle mesure prise en charge par l'environnement d'exécution.\nPar exemple : \"cuda_mem\", \"cuda_util\", etc : \"cuda_mem\", \"cuda_util\"",
"ScalingType": "Type",
"ScaleUp": "Augmentation d'échelle",
"ScaleDown": "Réduction d'échelle",
"Condition": "Condition"
},
"kernel": {
"KernelId": "ID du noyau",
Expand Down
7 changes: 6 additions & 1 deletion resources/i18n/id.json
Original file line number Diff line number Diff line change
Expand Up @@ -1785,7 +1785,12 @@
"MetricSource": "Sumber metrik",
"MIN/MAXReplicas": "Replika min / maks",
"LastTriggered": "Terakhir dipicu",
"CreatedAt": "Waktu yang dibuat"
"CreatedAt": "Waktu yang dibuat",
"ConditionTooltip": "Anda dapat dengan bebas memasukkan metrik apa pun yang didukung oleh lingkungan runtime.\nSebagai contoh: \"cuda_mem\", \"cuda_util\"",
"ScalingType": "Jenis",
"ScaleUp": "Meningkatkan Skala",
"ScaleDown": "Skala Turun",
"Condition": "Kondisi"
},
"kernel": {
"KernelId": "ID kernel",
Expand Down
7 changes: 6 additions & 1 deletion resources/i18n/it.json
Original file line number Diff line number Diff line change
Expand Up @@ -1783,7 +1783,12 @@
"MetricSource": "Fonte metrica",
"MIN/MAXReplicas": "Repliche min / max",
"LastTriggered": "Ultimo attivato",
"CreatedAt": "Tempo creato"
"CreatedAt": "Tempo creato",
"ConditionTooltip": "È possibile inserire liberamente qualsiasi metrica supportata dall'ambiente di runtime.\nAd esempio: \"cuda_mem\", \"cuda_util\".",
"ScalingType": "Tipo",
"ScaleUp": "Scalare",
"ScaleDown": "Riduzione della scala",
"Condition": "Condizione"
},
"kernel": {
"KernelId": "Kernel ID",
Expand Down
7 changes: 6 additions & 1 deletion resources/i18n/ja.json
Original file line number Diff line number Diff line change
Expand Up @@ -1785,7 +1785,12 @@
"MetricSource": "メトリックソース",
"MIN/MAXReplicas": "min / maxレプリカ",
"LastTriggered": "最後にトリガーされました",
"CreatedAt": "作成された時間"
"CreatedAt": "作成された時間",
"ConditionTooltip": "ランタイム環境でサポートされている任意の指標を自由に入力することができる。\nたとえば\"cuda_mem\"\"cuda_util\"",
"ScalingType": "タイプ",
"ScaleUp": "スケールアップ",
"ScaleDown": "スケールダウン",
"Condition": "コンディション"
},
"kernel": {
"KernelId": "カーネルID",
Expand Down
7 changes: 6 additions & 1 deletion resources/i18n/ko.json
Original file line number Diff line number Diff line change
Expand Up @@ -1789,7 +1789,12 @@
"MetricSource": "메트릭 소스",
"MIN/MAXReplicas": "최소 / 최대 복제본 수",
"LastTriggered": "최근 실행 시점",
"CreatedAt": "생성 시간"
"CreatedAt": "생성 시간",
"ScaleUp": "스케일 업",
"ScaleDown": "스케일 다운",
"Condition": "조건",
"ConditionTooltip": "실행 환경에서 지원하는 메트릭을 자유롭게 입력할 수 있습니다. 예) \"cuda_mem\", \"cuda_util\"",
"ScalingType": "타입"
},
"kernel": {
"KernelId": "커널 ID",
Expand Down
7 changes: 6 additions & 1 deletion resources/i18n/mn.json
Original file line number Diff line number Diff line change
Expand Up @@ -1784,7 +1784,12 @@
"MetricSource": "Метрийн эх сургай",
"MIN/MAXReplicas": "Мин / Макс хуулбарууд",
"LastTriggered": "Хамгийн сүүлд өдөөсөн",
"CreatedAt": "Үед"
"CreatedAt": "Үед",
"ConditionTooltip": "Ажиллах цагийн орчинд ямар ч хэмжигдэхүүнийг чөлөөтэй оруулж болно.\n\nЖишээлбэл: \"Cuda_mem\", \"Cuda_util\"",
"ScalingType": "Маяг",
"ScaleUp": "Газар дамжуулах",
"ScaleDown": "Хэмжээ",
"Condition": "Болзол"
},
"kernel": {
"KernelId": "Kernel ID",
Expand Down
7 changes: 6 additions & 1 deletion resources/i18n/ms.json
Original file line number Diff line number Diff line change
Expand Up @@ -1785,7 +1785,12 @@
"MetricSource": "Sumber metrik",
"MIN/MAXReplicas": "Replika min / max",
"LastTriggered": "Yang terakhir dicetuskan",
"CreatedAt": "Masa yang dicipta"
"CreatedAt": "Masa yang dicipta",
"ConditionTooltip": "Anda boleh memasukkan mana -mana metrik yang disokong oleh persekitaran runtime.\n\nContohnya: \"CUDA_MEM\", \"CUDA_UTIL\"",
"ScalingType": "Jenis",
"ScaleUp": "Skala",
"ScaleDown": "Skala ke bawah",
"Condition": "Keadaan"
},
"kernel": {
"KernelId": "ID Kernel",
Expand Down
7 changes: 6 additions & 1 deletion resources/i18n/pl.json
Original file line number Diff line number Diff line change
Expand Up @@ -1785,7 +1785,12 @@
"MetricSource": "Źródło metryczne",
"MIN/MAXReplicas": "Repliki min / max",
"LastTriggered": "Ostatni wyzwolenie",
"CreatedAt": "Utworzony czas"
"CreatedAt": "Utworzony czas",
"ConditionTooltip": "Możesz dowolnie wprowadzić dowolną metrykę obsługiwaną przez środowisko wykonawcze.\nNa przykład: \"cuda_mem\", \"cuda_util\"",
"ScalingType": "Typ",
"ScaleUp": "Zwiększanie skali",
"ScaleDown": "Skalowanie w dół",
"Condition": "Stan"
},
"kernel": {
"KernelId": "ID jądra",
Expand Down
7 changes: 6 additions & 1 deletion resources/i18n/pt-BR.json
Original file line number Diff line number Diff line change
Expand Up @@ -1785,7 +1785,12 @@
"MetricSource": "Fonte métrica",
"MIN/MAXReplicas": "Min / Max Replicas",
"LastTriggered": "Último desencadeado",
"CreatedAt": "Tempo criado"
"CreatedAt": "Tempo criado",
"ConditionTooltip": "Pode introduzir livremente qualquer métrica suportada pelo ambiente de tempo de execução.\nPor exemplo: \"cuda_mem\", \"cuda_util\"",
"ScalingType": "Tipo",
"ScaleUp": "Aumentar a escala",
"ScaleDown": "Reduzir a escala",
"Condition": "Estado"
},
"kernel": {
"KernelId": "ID do kernel",
Expand Down
7 changes: 6 additions & 1 deletion resources/i18n/pt.json
Original file line number Diff line number Diff line change
Expand Up @@ -1785,7 +1785,12 @@
"MetricSource": "Fonte métrica",
"MIN/MAXReplicas": "Min / Max Replicas",
"LastTriggered": "Último desencadeado",
"CreatedAt": "Tempo criado"
"CreatedAt": "Tempo criado",
"ConditionTooltip": "Pode introduzir livremente qualquer métrica suportada pelo ambiente de tempo de execução.\nPor exemplo: \"cuda_mem\", \"cuda_util\"",
"ScalingType": "Tipo",
"ScaleUp": "Aumentar a escala",
"ScaleDown": "Reduzir a escala",
"Condition": "Estado"
},
"kernel": {
"KernelId": "ID do kernel",
Expand Down
7 changes: 6 additions & 1 deletion resources/i18n/ru.json
Original file line number Diff line number Diff line change
Expand Up @@ -1785,7 +1785,12 @@
"MetricSource": "Метрический источник",
"MIN/MAXReplicas": "Мин / максимальные реплики",
"LastTriggered": "Последний вызван",
"CreatedAt": "Создано время"
"CreatedAt": "Создано время",
"ConditionTooltip": "Вы можете свободно ввести любую метрику, поддерживаемую средой выполнения.\nНапример: \"cuda_mem\", \"cuda_util\".",
"ScalingType": "Тип",
"ScaleUp": "Увеличение масштаба",
"ScaleDown": "Уменьшение масштаба",
"Condition": "Состояние"
},
"kernel": {
"KernelId": "Ядро идентификатор",
Expand Down
7 changes: 6 additions & 1 deletion resources/i18n/th.json
Original file line number Diff line number Diff line change
Expand Up @@ -1766,7 +1766,12 @@
"MetricSource": "แหล่งวัด",
"MIN/MAXReplicas": "แบบจำลองขั้นต่ำ / สูงสุด",
"LastTriggered": "ทริกเกอร์ครั้งสุดท้าย",
"CreatedAt": "สร้างเวลา"
"CreatedAt": "สร้างเวลา",
"ConditionTooltip": "คุณสามารถป้อนตัวชี้วัดใด ๆ ที่รองรับโดยสภาพแวดล้อมรันไทม์ได้อย่างอิสระ\n\nตัวอย่างเช่น: \"cuda_mem\", \"cuda_util\"",
"ScalingType": "พิมพ์",
"ScaleUp": "ขยาย",
"ScaleDown": "ลดขนาดลง",
"Condition": "เงื่อนไข"
},
"kernel": {
"KernelId": "ID เคอร์เนล",
Expand Down
Loading

0 comments on commit a777826

Please sign in to comment.