Skip to content

Commit 0906fa1

Browse files
committed
feature: Aplication memory bar
1 parent 832cd37 commit 0906fa1

3 files changed

Lines changed: 266 additions & 4 deletions

File tree

react/src/components/DynamicUnitInputNumberWithSlider.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import DynamicUnitInputNumber, {
66
} from './DynamicUnitInputNumber';
77
import Flex from './Flex';
88
import { Slider, theme } from 'antd';
9-
import { SliderMarks } from 'antd/es/slider';
9+
import { SliderMarks, SliderProps } from 'antd/es/slider';
1010
import _ from 'lodash';
1111
import React, { useEffect, useMemo } from 'react';
1212

@@ -16,6 +16,7 @@ export interface DynamicUnitInputNumberWithSliderProps
1616
hideSlider?: boolean;
1717
warn?: string;
1818
step?: number;
19+
sliderProps?: SliderProps;
1920
}
2021
const DynamicUnitInputNumberWithSlider: React.FC<
2122
DynamicUnitInputNumberWithSliderProps

react/src/components/ResourceAllocationFormItems.tsx

Lines changed: 250 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import {
22
addNumberWithUnits,
33
compareNumberWithUnits,
44
convertBinarySizeUnit,
5+
subNumberWihUnits,
56
} from '../helper';
67
import { useSuspendedBackendaiClient, useUpdatableState } from '../hooks';
78
import { useResourceSlotsDetails } from '../hooks/backendai';
@@ -15,6 +16,8 @@ import {
1516
} from '../hooks/useResourceLimitAndRemaining';
1617
import AgentSelect from './AgentSelect';
1718
import BAISelect from './BAISelect';
19+
import DynamicInputNumber from './DynamicStepInputNumber';
20+
import DynamicUnitInputNumber from './DynamicUnitInputNumber';
1821
import DynamicUnitInputNumberWithSlider from './DynamicUnitInputNumberWithSlider';
1922
import Flex from './Flex';
2023
// import FormItemControl from './FormItemControl';
@@ -23,6 +26,7 @@ import {
2326
ImageEnvironmentFormInput,
2427
} from './ImageEnvironmentSelectFormItems';
2528
import InputNumberWithSlider from './InputNumberWithSlider';
29+
import QuestionIconWithTooltip from './QuestionIconWithTooltip';
2630
import ResourceGroupSelect from './ResourceGroupSelect';
2731
import ResourcePresetSelect from './ResourcePresetSelect';
2832
import { ResourceAllocationFormItemsQuery } from './__generated__/ResourceAllocationFormItemsQuery.graphql';
@@ -31,14 +35,18 @@ import {
3135
Button,
3236
Card,
3337
Col,
38+
ConfigProvider,
3439
Divider,
3540
Form,
41+
InputNumber,
3642
Radio,
3743
Row,
44+
Slider,
3845
Switch,
3946
theme,
4047
} from 'antd';
4148
import graphql from 'babel-plugin-relay/macro';
49+
import { log } from 'console';
4250
import _ from 'lodash';
4351
import React, { Suspense, useEffect, useMemo, useTransition } from 'react';
4452
import { Trans, useTranslation } from 'react-i18next';
@@ -838,8 +846,246 @@ const ResourceAllocationFormItems: React.FC<
838846
);
839847
}}
840848
</Form.Item>
849+
<Form.Item
850+
noStyle
851+
dependencies={[
852+
['resource', 'mem'],
853+
['resource', 'shmem'],
854+
['enabledAutomaticShmem'],
855+
]}
856+
>
857+
{({ getFieldValue }) => {
858+
const mem = getFieldValue(['resource', 'mem']);
859+
const shmem = getFieldValue(['resource', 'shmem']);
860+
const memUnitResult = convertBinarySizeUnit(
861+
mem,
862+
'auto',
863+
2,
864+
);
865+
const shmemUnitResult = convertBinarySizeUnit(
866+
shmem,
867+
'auto',
868+
2,
869+
);
870+
const appMemUnitResult = convertBinarySizeUnit(
871+
(convertBinarySizeUnit(mem, 'b')?.number || 0) -
872+
(convertBinarySizeUnit(shmem, 'b')?.number || 0) +
873+
'b',
874+
memUnitResult?.unit,
875+
);
876+
const isAutoShmem = getFieldValue(
877+
'enabledAutomaticShmem',
878+
);
879+
880+
return (
881+
<Flex direction="column" align="stretch">
882+
{/* <Form.Item name={['resource', 'shmem']}> */}
883+
<Flex direction="row" gap={'sm'}>
884+
<ConfigProvider
885+
theme={{
886+
components: {
887+
Slider: {
888+
railBg: token.colorWarning,
889+
railHoverBg: token.colorWarning,
890+
trackBg: token.colorSuccess,
891+
trackHoverBg: token.colorSuccess,
892+
railSize: token.fontSize,
893+
},
894+
},
895+
}}
896+
>
897+
<Slider
898+
style={{
899+
flex: 1,
900+
margin: 0,
901+
cursor: 'default',
902+
}}
903+
styles={{
904+
handle: {
905+
// display: isAutoShmem ? 'none' : undefined,
906+
display: 'none',
907+
},
908+
}}
909+
value={appMemUnitResult?.number}
910+
max={memUnitResult?.number}
911+
/>
912+
</ConfigProvider>
913+
</Flex>
914+
{/* </Form.Item> */}
915+
<Flex direction="row" gap={'xxs'} justify="between">
916+
<Flex gap={'xxs'}>
917+
<div
918+
style={{
919+
height: token.fontSize,
920+
width: token.fontSize,
921+
backgroundColor: token.colorSuccess,
922+
}}
923+
></div>
924+
Application MEM {appMemUnitResult?.numberUnit}
925+
</Flex>
926+
<Flex gap={'xxs'}>
927+
<div
928+
style={{
929+
height: token.fontSize,
930+
width: token.fontSize,
931+
backgroundColor: token.colorWarning,
932+
}}
933+
></div>
841934

842-
<Flex direction="column" gap={'xxs'} align="start">
935+
{getFieldValue('enabledAutomaticShmem') ? (
936+
`SHMEM ${shmemUnitResult?.numberUnit}`
937+
) : (
938+
<Form.Item
939+
noStyle
940+
name={['resource', 'shmem']}
941+
// initialValue={'0g'}
942+
// label={t('session.launcher.SharedMemory')}
943+
hidden={form.getFieldValue(
944+
'enabledAutomaticShmem',
945+
)}
946+
tooltip={
947+
<Trans
948+
i18nKey={
949+
'session.launcher.DescSharedMemory'
950+
}
951+
/>
952+
}
953+
dependencies={[['resource', 'mem']]}
954+
rules={[
955+
{
956+
required: true,
957+
},
958+
{},
959+
{
960+
warningOnly: true,
961+
validator: async (
962+
rule,
963+
value: string,
964+
) => {
965+
const applicationMem =
966+
appMemUnitResult?.numberUnit;
967+
const shmem = value;
968+
969+
if (
970+
_.isEmpty(applicationMem) ||
971+
_.isEmpty(shmem)
972+
) {
973+
return Promise.resolve();
974+
}
975+
976+
if (
977+
(convertBinarySizeUnit(
978+
applicationMem,
979+
'M',
980+
)?.number || 0) <
981+
(convertBinarySizeUnit(shmem, 'M')
982+
?.number || 0) *
983+
2
984+
) {
985+
throw '공유 메모리는 Application MEM의 절반 이하가 권장됩니다.';
986+
} else {
987+
return Promise.resolve();
988+
}
989+
},
990+
},
991+
992+
{
993+
validator: async (
994+
rule,
995+
value: string,
996+
) => {
997+
if (
998+
_.isEmpty(
999+
getFieldValue('resource')?.mem,
1000+
) ||
1001+
_.isEmpty(value) ||
1002+
compareNumberWithUnits(
1003+
getFieldValue('resource')?.mem,
1004+
value,
1005+
) >= 0
1006+
) {
1007+
return Promise.resolve();
1008+
} else {
1009+
throw t(
1010+
'resourcePreset.SHMEMShouldBeSmallerThanMemory',
1011+
);
1012+
}
1013+
},
1014+
},
1015+
]}
1016+
>
1017+
<DynamicUnitInputNumber
1018+
// shmem max is mem max
1019+
// min={resourceLimits.shmem?.min}
1020+
min={resourceLimits.shmem?.min}
1021+
size="small"
1022+
// max={resourceLimits.mem?.max || '0g'}
1023+
addonBefore={'SHM'}
1024+
max={
1025+
form.getFieldValue([
1026+
'resource',
1027+
'mem',
1028+
]) || '0g'
1029+
}
1030+
style={{
1031+
width: 200,
1032+
}}
1033+
onChange={() => {
1034+
form.setFieldValue(
1035+
'allocationPreset',
1036+
'custom',
1037+
);
1038+
}}
1039+
/>
1040+
</Form.Item>
1041+
// <DynamicUnitInputNumber
1042+
// value={shmem}
1043+
// onChange={() => {}}
1044+
// size="small"
1045+
// variant="outlined"
1046+
// addonBefore={'SHMEM'}
1047+
// style={{
1048+
// width: 200,
1049+
// }}
1050+
// />
1051+
)}
1052+
<Flex direction="row" gap="xs">
1053+
<Form.Item
1054+
noStyle
1055+
name={'enabledAutomaticShmem'}
1056+
valuePropName="checked"
1057+
>
1058+
<Switch
1059+
size="small"
1060+
title="auto"
1061+
checkedChildren={'AUTO'}
1062+
unCheckedChildren={'MANUAL'}
1063+
onChange={(checked) => {
1064+
if (checked) {
1065+
runShmemAutomationRule(
1066+
form.getFieldValue([
1067+
'resource',
1068+
'mem',
1069+
]) || '0g',
1070+
);
1071+
}
1072+
form.setFieldValue(
1073+
'allocationPreset',
1074+
'custom',
1075+
);
1076+
}}
1077+
/>
1078+
</Form.Item>
1079+
<QuestionIconWithTooltip title="할당한 메모리 내에서 공유 메모리로 사용할 크기를 자동 선택하거나 수동으로 입력할 수 있습니다." />
1080+
</Flex>
1081+
</Flex>
1082+
</Flex>
1083+
</Flex>
1084+
);
1085+
}}
1086+
</Form.Item>
1087+
1088+
{/* <Flex direction="column" gap={'xxs'} align="start">
8431089
<Flex direction="row" gap={'xs'}>
8441090
{t('session.launcher.EnableAutomaticMiniumShmem')}{' '}
8451091
<Form.Item
@@ -870,6 +1116,7 @@ const ResourceAllocationFormItems: React.FC<
8701116
}
8711117
>
8721118
{() => {
1119+
return null;
8731120
return (
8741121
<Form.Item
8751122
noStyle
@@ -934,9 +1181,10 @@ const ResourceAllocationFormItems: React.FC<
9341181
);
9351182
}}
9361183
</Form.Item>
937-
</Flex>
1184+
</Flex> */}
9381185
</Form.Item>
9391186
)}
1187+
9401188
<Form.Item
9411189
noStyle
9421190
shouldUpdate={(prev, next) => {

react/src/helper/index.tsx

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -201,7 +201,7 @@ function convertSizeUnit(
201201
return {
202202
number: finalBytes,
203203
numberFixed,
204-
unit: sizes[targetIndex],
204+
unit: sizes[targetIndex] as SizeUnit,
205205
numberUnit: `${numberFixed}${sizes[targetIndex]}`,
206206
};
207207
}
@@ -267,6 +267,19 @@ export function addNumberWithUnits(
267267
)?.numberUnit;
268268
}
269269

270+
export function subNumberWihUnits(
271+
size1: string,
272+
size2: string,
273+
targetUnit: SizeUnit = 'm',
274+
) {
275+
return convertBinarySizeUnit(
276+
(convertBinarySizeUnit(size1, 'b')?.number || 0) -
277+
(convertBinarySizeUnit(size2, 'b')?.number || 0) +
278+
'b',
279+
targetUnit,
280+
)?.numberUnit;
281+
}
282+
270283
export type QuotaScopeType = 'project' | 'user';
271284
export const addQuotaScopeTypePrefix = (type: QuotaScopeType, str: string) => {
272285
if (str === '' || str === undefined) return '';

0 commit comments

Comments
 (0)