Skip to content

Commit

Permalink
Merge pull request #180 from parsecph/feature/logs-perf
Browse files Browse the repository at this point in the history
Improve performance of response logs
  • Loading branch information
danmindru authored Oct 15, 2023
2 parents d546a0e + 7aad128 commit 5b13bc1
Show file tree
Hide file tree
Showing 30 changed files with 8,780 additions and 8,928 deletions.
4 changes: 2 additions & 2 deletions packages/share/components/parseResults.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,6 @@ export const parseResult = (
verb: parsed.v as any,
url: parsed.u,
latestResult: {
id: '',
startDate: parsed.lr.s,
endDate: parsed.lr.e,
iterations: parsed.lr.i,
Expand All @@ -100,7 +99,8 @@ export const parseResult = (
},

// Unkown
id: '',
cacheId: '',
listItemId: '',
timeout: 0,
headers: [],
data: {}
Expand Down
1 change: 1 addition & 0 deletions packages/ui/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
"@types/uuid": "^8.3.4",
"@uiw/react-monacoeditor": "^3.5.3",
"axios": "^0.26.1",
"brotli-wasm": "^2.0.1",
"byte-size": "^8.1.0",
"chart.js": "^3.9.1",
"chartjs-plugin-trendline": "^2.0.0",
Expand Down
2 changes: 1 addition & 1 deletion packages/ui/public/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta
http-equiv="Content-Security-Policy"
content="script-src 'self' blob:;"
content="script-src 'unsafe-eval' 'self' blob:;"
/>

<link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
Expand Down
35 changes: 33 additions & 2 deletions packages/ui/src/app/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,11 @@ import { ToastContainer } from 'toasts/toastContainer';
import { useStoredPreferences } from 'shared/hooks/useStoredPreferences';
import { ClobbrUIListItem } from 'models/ClobbrUIListItem';
import { useToastStore } from 'toasts/state/toastStore';
import {
isResultInProgress,
isResultPartiallyComplete
} from 'results/Result/useResultProperties';
import { UI_RESULT_STATES } from 'models/ClobbrUIResult';

const App = () => {
const toasts = useToastStore((state) => state.toasts);
Expand Down Expand Up @@ -63,7 +68,8 @@ const App = () => {
});

const expandedResult = state.results.list.find(
(item: ClobbrUIListItem) => item.id === state.results.expandedResults[0]
(item: ClobbrUIListItem) =>
item.listItemId === state.results.expandedResults[0]
);

// Result state
Expand All @@ -73,7 +79,32 @@ const App = () => {
}

if (storedResultState.value) {
state.results.setList(storedResultState.value);
try {
// Update unfinised results & set them to partially finished.
const resultList = storedResultState.value.map(
(item: ClobbrUIListItem) => {
const isPartiallyComplete = isResultPartiallyComplete({
resultState: item.latestResult.state
});

const isInProgress = isResultInProgress({
logs: item.latestResult.logs,
iterations: item.latestResult.iterations,
isPartiallyComplete
});

if (isInProgress) {
item.latestResult.state = UI_RESULT_STATES.PARTIALLY_COMPLETED;
}

return item;
}
);

state.results.setList(resultList);
} catch (error) {
console.error(error);
}
}

setResultStorageLoaded(true);
Expand Down
16 changes: 4 additions & 12 deletions packages/ui/src/app/globalContext.ts
Original file line number Diff line number Diff line change
Expand Up @@ -98,23 +98,15 @@ export const DEFAULT_GLOBAL_STORE = {
data: { [key: string]: any };
properties?: ClobbrUIProperties;
timeout: number;
}): { id: string } {
return { id: '' };
}): { listItemId: string; cacheId: string } {
return { listItemId: '', cacheId: '' };
},

addLatestResultLog({
itemId,
log
}: {
itemId: string;
log: ClobbrLogItem;
}) {},

updateLatestResult({
itemId,
cacheId,
logs
}: {
itemId: string;
cacheId: string;
logs: Array<ClobbrLogItem>;
}) {}
},
Expand Down
3 changes: 2 additions & 1 deletion packages/ui/src/models/ClobbrUICachedLog.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
export interface ClobbrUICachedLog {
index: number;
data?: { [key: string]: string } | string;
data?: string;
error?: string;
}
3 changes: 2 additions & 1 deletion packages/ui/src/models/ClobbrUIListItem.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@ import { ClobbrUIProperties } from './ClobbrUIProperties';

export interface ClobbrUIListItem {
properties?: ClobbrUIProperties;
id: string;
listItemId: string;
cacheId: string;
url: string;
latestResult: ClobbrUIResult;
parallel: boolean;
Expand Down
11 changes: 9 additions & 2 deletions packages/ui/src/models/ClobbrUIResult.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,15 @@
import { ClobbrUIHeaderItem } from 'models/ClobbrUIHeaderItem';
import { ClobbrLogItem } from '@clobbr/api/src/models/ClobbrLog';

export const UI_RESULT_STATES = {
PARTIALLY_COMPLETED: 'PARTIALLY_COMPLETED'
};

export type ClobbrUIResultState =
typeof UI_RESULT_STATES[keyof typeof UI_RESULT_STATES];

export interface ClobbrUIResult {
id: string;
cachedId: string;
cacheId: string;
startDate?: string;
endDate?: string;
resultDurations: Array<number>;
Expand All @@ -21,4 +27,5 @@ export interface ClobbrUIResult {
};
data?: { [key: string]: any };
timeout: number;
state?: ClobbrUIResultState;
}
32 changes: 20 additions & 12 deletions packages/ui/src/results/Result/Result.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,9 @@ const Result = ({
className?: string;
listItemClassName?: string;
}) => {
const { allFailed, timedOut, isInProgress } = useResultProperties({ item });
const { allFailed, isPartiallyComplete, isInProgress } = useResultProperties({
item
});

const resultDom = useRef(null);
const globalStore = useContext(GlobalStore);
Expand Down Expand Up @@ -96,7 +98,7 @@ const Result = ({
if (expanded) {
globalStore.results.updateExpandedResults([]);
} else {
globalStore.results.updateExpandedResults([item.id]);
globalStore.results.updateExpandedResults([item.listItemId]);

setTimeout(() => {
if (resultDom?.current) {
Expand All @@ -113,7 +115,7 @@ const Result = ({
const currentScroll = document.documentElement.scrollTop;

const nextResultList = globalStore.results.listRef.current.filter(
(result: ClobbrUIListItem) => result.id !== item.id
(result: ClobbrUIListItem) => result.listItemId !== item.listItemId
);
globalStore.results.setList(nextResultList);

Expand Down Expand Up @@ -229,7 +231,7 @@ const Result = ({
/>

<div className="flex flex-col flex-shrink-0 gap-1 items-end justify-between">
{!allFailed && !timedOut ? (
{!allFailed ? (
<Tooltip title="Average response time (mean)">
<Typography
variant="body2"
Expand All @@ -250,14 +252,6 @@ const Result = ({
''
)}

{timedOut ? (
<Typography variant="body2" className="opacity-50">
Timed out
</Typography>
) : (
''
)}

<Typography
variant="caption"
className="flex items-center gap-1 justify-center opacity-50"
Expand All @@ -278,6 +272,20 @@ const Result = ({
<CloseIcon className={xIconCss} />
</span>
</Tooltip>

{isPartiallyComplete ? (
<Tooltip
title={`${item.latestResult.logs.length} ${
item.latestResult.logs.length === 1 ? 'call' : 'calls'
} ran`}
>
<Typography variant="body2" className="opacity-50">
Partial
</Typography>
</Tooltip>
) : (
''
)}
</Typography>
</div>
</ButtonBase>
Expand Down
38 changes: 2 additions & 36 deletions packages/ui/src/results/Result/ResultContent/ResultContent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import { Typography } from '@mui/material';
import Tooltip from '@mui/material/Tooltip';

import { ReactComponent as AllFailed } from 'shared/images/search/AllFailed.svg';
import { ReactComponent as Timeout } from 'shared/images/search/Timeout.svg';

import { ResultChart } from 'results/ResultChart/ResultChart';
import { ResultStats } from 'results/ResultStats/ResultStats';
Expand All @@ -34,7 +33,6 @@ const ResultContent = ({

const {
allFailed,
timedOut,
isInProgress,
failedItems,
successfulItems,
Expand All @@ -51,11 +49,7 @@ const ResultContent = ({
globalStore.appSettings.chartDownSampleThreshold;

const shouldShowChart =
!allFailed &&
!timedOut &&
expanded &&
item.iterations > 1 &&
successfulItems.length > 1;
!allFailed && expanded && item.iterations > 1 && successfulItems.length > 1;

return (
<AnimatePresence>
Expand Down Expand Up @@ -117,35 +111,7 @@ const ResultContent = ({
''
)}

{expanded && timedOut ? (
<div className="flex flex-col gap-4 pb-12 items-center">
<Timeout className="w-full max-w-xs p-6" />
<Typography variant="body1">
<strong className="font-semibold">Requests timed out</strong>
</Typography>

<Typography variant="body2" className="opacity-50">
Try reducing the number of iterations and run again? <br />
</Typography>

<div className="w-full absolute z-40 flex gap-4 justify-center -mt-10">
<ResultHistoryToggle item={item} className="" />
</div>

<div className="flex gap-2 mt-4">
<ReRunResultButton item={item} />
<UpdateSettingsButton item={item} />
</div>
</div>
) : (
''
)}

{expanded &&
!isInProgress &&
!shouldShowChart &&
!timedOut &&
!allFailed ? (
{expanded && !isInProgress && !shouldShowChart && !allFailed ? (
<>
<Typography variant="body2" className="opacity-50 text-center">
Increase the number of itetations to see more stats.
Expand Down
66 changes: 44 additions & 22 deletions packages/ui/src/results/Result/useResultProperties.ts
Original file line number Diff line number Diff line change
@@ -1,33 +1,48 @@
import { useMemo } from 'react';
import differenceInMinutes from 'date-fns/differenceInMinutes';

import { ClobbrUIListItem } from 'models/ClobbrUIListItem';
import { ClobbrUIResultState, UI_RESULT_STATES } from 'models/ClobbrUIResult';

const TIMEOUT_WAIT_IN_MINUTES = 3;

export const useResultProperties = ({ item }: { item?: ClobbrUIListItem }) => {
const itemInternal = item || {
latestResult: {
endDate: new Date(),
startDate: new Date()
}
};
export const isResultTimeout = ({
startDate,
endDate
}: {
startDate: string;
endDate?: string | Date;
}): boolean => {
return !!(
startDate &&
!endDate &&
differenceInMinutes(new Date(), new Date(startDate)) >
TIMEOUT_WAIT_IN_MINUTES
);
};

const timedOut = useMemo(() => {
const startDate = itemInternal.latestResult.startDate as string;
const endDate = itemInternal.latestResult.endDate;
export const isResultInProgress = ({
isPartiallyComplete,
logs,
iterations
}: {
isPartiallyComplete: boolean;
logs: Array<any>;
iterations: number;
}) => {
return !isPartiallyComplete && logs.length !== iterations;
};

return !!(
startDate &&
!endDate &&
differenceInMinutes(new Date(), new Date(startDate)) >
TIMEOUT_WAIT_IN_MINUTES
);
}, [itemInternal.latestResult.startDate, itemInternal.latestResult.endDate]);
export const isResultPartiallyComplete = ({
resultState
}: {
resultState?: ClobbrUIResultState;
}) => {
return resultState === UI_RESULT_STATES.PARTIALLY_COMPLETED;
};

export const useResultProperties = ({ item }: { item?: ClobbrUIListItem }) => {
if (!item) {
return {
timedOut: false,
isInProgress: false,
successfulItems: [],
failedItems: [],
Expand All @@ -36,8 +51,15 @@ export const useResultProperties = ({ item }: { item?: ClobbrUIListItem }) => {
};
}

const isInProgress =
!timedOut && item.latestResult.logs.length !== item.iterations;
const isPartiallyComplete = isResultPartiallyComplete({
resultState: item.latestResult.state
});

const isInProgress = isResultInProgress({
logs: item.latestResult.logs,
iterations: item.iterations,
isPartiallyComplete
});

const successfulItems = item.latestResult.logs.filter((log) => !log.failed);

Expand All @@ -48,8 +70,8 @@ export const useResultProperties = ({ item }: { item?: ClobbrUIListItem }) => {
const pctOfSuccess = (successfulItems.length * 100) / item.iterations;

return {
timedOut,
isInProgress,
isPartiallyComplete,
successfulItems,
failedItems,
allFailed,
Expand Down
Loading

1 comment on commit 5b13bc1

@vercel
Copy link

@vercel vercel bot commented on 5b13bc1 Oct 15, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.