From a6556d17383f776f57660b71e1d35522811da399 Mon Sep 17 00:00:00 2001 From: hhzscreate <986304049@qq.com> Date: Thu, 23 Jul 2026 15:38:15 +0800 Subject: [PATCH] [#noissue] Fix bug: Server Map and Service Map read the `useStatisticsAgentState` experimental option with`value || true`. JavaScript treats an explicit `false` as falsy, so the expression always evaluates to `true`. Users and server-side configuration therefore cannot disable the feature. --- .../components/ServerMap/ServerMapFetcher.tsx | 11 +++++++-- .../ServiceMap/ServiceMapFetcher.tsx | 23 ++++++++++++++----- .../ui/src/utils/helper/serverMap.test.ts | 21 +++++++++++++---- .../packages/ui/src/utils/helper/serverMap.ts | 3 +++ 4 files changed, 45 insertions(+), 13 deletions(-) diff --git a/web-frontend/src/main/v3/packages/ui/src/components/ServerMap/ServerMapFetcher.tsx b/web-frontend/src/main/v3/packages/ui/src/components/ServerMap/ServerMapFetcher.tsx index d14c7c097157..f47e77d1a075 100644 --- a/web-frontend/src/main/v3/packages/ui/src/components/ServerMap/ServerMapFetcher.tsx +++ b/web-frontend/src/main/v3/packages/ui/src/components/ServerMap/ServerMapFetcher.tsx @@ -12,7 +12,12 @@ import { useServerMapSearchParameters, } from '@pinpoint-fe/ui/src/hooks'; import { useTranslation } from 'react-i18next'; -import { getBaseNodeId, getServerImagePath, parseBaseNodeId } from '@pinpoint-fe/ui/src/utils'; +import { + getBaseNodeId, + getServerImagePath, + parseBaseNodeId, + resolveUseStatisticsAgentState, +} from '@pinpoint-fe/ui/src/utils'; import { ServerMapCore, ServerMapCoreProps } from './ServerMapCore'; export interface ServerMapFetcherProps extends Pick< @@ -28,7 +33,9 @@ export const ServerMapFetcher = ({ shouldPoll, ...props }: ServerMapFetcherProps const setServerMapCurrentTarget = useSetAtom(serverMapCurrentTargetAtom); const { application } = useServerMapSearchParameters(); const experimentalOption = useExperimentals(); - const useStatisticsAgentState = experimentalOption.statisticsAgentState.value || true; + const useStatisticsAgentState = resolveUseStatisticsAgentState( + experimentalOption.statisticsAgentState.value, + ); const { data, isLoading, error } = useGetServerMapDataV2({ shouldPoll: !!shouldPoll, diff --git a/web-frontend/src/main/v3/packages/ui/src/components/ServiceMap/ServiceMapFetcher.tsx b/web-frontend/src/main/v3/packages/ui/src/components/ServiceMap/ServiceMapFetcher.tsx index c5630f9a1dc5..aadf7dbbf471 100644 --- a/web-frontend/src/main/v3/packages/ui/src/components/ServiceMap/ServiceMapFetcher.tsx +++ b/web-frontend/src/main/v3/packages/ui/src/components/ServiceMap/ServiceMapFetcher.tsx @@ -18,26 +18,37 @@ import { getBaseNodeId, getServerImagePath, parseBaseNodeId, + resolveUseStatisticsAgentState, toBasicISOString, } from '@pinpoint-fe/ui/src/utils'; import { ServerMapCore, ServerMapCoreProps } from '../ServerMap/ServerMapCore'; -export interface ServiceMapFetcherProps - extends Pick { +export interface ServiceMapFetcherProps extends Pick< + ServerMapCoreProps, + 'onClickMenuItem' | 'onApplyChangedOption' | 'queryOption' +> { shouldPoll?: boolean; } -export const ServiceMapFetcher = ({ shouldPoll: _shouldPoll, ...props }: ServiceMapFetcherProps) => { +export const ServiceMapFetcher = ({ + shouldPoll: _shouldPoll, + ...props +}: ServiceMapFetcherProps) => { const setDataAtom = useSetAtom(serverMapDataAtom); const setCurrentServer = useSetAtom(currentServerAtom); const setServerMapCurrentTarget = useSetAtom(serverMapCurrentTargetAtom); const serverMapCurrentTarget = useAtomValue(serverMapCurrentTargetAtom); const { application, dateRange } = useServerMapSearchParameters(); const experimentalOption = useExperimentals(); - const useStatisticsAgentState = - experimentalOption[EXPERIMENTAL_CONFIG_KEYS.USE_STATISTICS_AGENT_STATE].value || true; + const useStatisticsAgentState = resolveUseStatisticsAgentState( + experimentalOption[EXPERIMENTAL_CONFIG_KEYS.USE_STATISTICS_AGENT_STATE].value, + ); - const { data: rawData, isLoading, error } = useGetServiceMap({ + const { + data: rawData, + isLoading, + error, + } = useGetServiceMap({ applicationName: application?.applicationName ?? '', serviceTypeName: application?.serviceType, from: toBasicISOString(dateRange.from), diff --git a/web-frontend/src/main/v3/packages/ui/src/utils/helper/serverMap.test.ts b/web-frontend/src/main/v3/packages/ui/src/utils/helper/serverMap.test.ts index 98fbef6d93f8..b5a3ebdd9a26 100644 --- a/web-frontend/src/main/v3/packages/ui/src/utils/helper/serverMap.test.ts +++ b/web-frontend/src/main/v3/packages/ui/src/utils/helper/serverMap.test.ts @@ -1,4 +1,4 @@ -import { getBaseNodeId, getTimeSeriesApdexInfo } from './serverMap'; +import { getBaseNodeId, getTimeSeriesApdexInfo, resolveUseStatisticsAgentState } from './serverMap'; import { ApplicationType, GetServerMap, @@ -6,10 +6,22 @@ import { } from '@pinpoint-fe/ui/src/constants'; describe('Test serverMap helper utils', () => { + describe('Test "resolveUseStatisticsAgentState"', () => { + test('Preserve an explicitly disabled option', () => { + expect(resolveUseStatisticsAgentState(false)).toBe(false); + }); + + test('Preserve an explicitly enabled option', () => { + expect(resolveUseStatisticsAgentState(true)).toBe(true); + }); + + test.each([null, undefined])('Use the fallback when the option is %s', (value) => { + expect(resolveUseStatisticsAgentState(value)).toBe(true); + }); + }); + describe('Test "getTimeSeriesApdexInfo"', () => { - const makeNode = ( - overrides: Partial = {}, - ): GetServerMap.NodeData => + const makeNode = (overrides: Partial = {}): GetServerMap.NodeData => ({ isAuthorized: true, apdexSlot: [], @@ -56,7 +68,6 @@ describe('Test serverMap helper utils', () => { }); }); - describe('Test "getBaseNodeId"', () => { test('Return base node ID when node list is empty', () => { const application: ApplicationType = { diff --git a/web-frontend/src/main/v3/packages/ui/src/utils/helper/serverMap.ts b/web-frontend/src/main/v3/packages/ui/src/utils/helper/serverMap.ts index 0cda7a50f9d2..3f5edd2fc5a0 100644 --- a/web-frontend/src/main/v3/packages/ui/src/utils/helper/serverMap.ts +++ b/web-frontend/src/main/v3/packages/ui/src/utils/helper/serverMap.ts @@ -8,6 +8,9 @@ import { Edge as ServerMapEdge, Node as ServerMapNode } from '@pinpoint-fe/serve export type Edge = ServerMapEdge; export type Node = ServerMapNode; +export const resolveUseStatisticsAgentState = (value: boolean | null | undefined): boolean => + value ?? true; + // node/link key는 2-part(applicationName^serviceType) 또는 3-part(serviceName^applicationName^serviceType)로 들어올 수 있다. // 마지막 두 토큰이 항상 [applicationName, serviceType]이므로 뒤에서 잘라낸다. export const parseBaseNodeId = (