Skip to content

Commit f44872b

Browse files
sanni-tncdiehlncdiehl11
authored
feat(robot-server, app): add a new endpoint for fast-fetching all run commands (#15031)
# Overview **Robot server changes:** Adds a new endpoint- `GET /runs/:run_id/commandsAsPreSerializedList` to the run commands router. This endpoint returns a list of pre-serialized commands (that are valid json objects) of a finished run. This endpoint is a much faster alternative to the `GET /runs/:run_id/commands` endpoint when fetching all commands of a completed run. Also adds notification publishing when pre-serialized commands become available for a run. **App changes** closes RQA-2645 and RQA-2647 # Risk assessment Back-end: New endpoint so impact on existing code is close to none. App: Medium. Fixes issues in existing behavior of handling historical runs. --------- Co-authored-by: ncdiehl11 <[email protected]> Co-authored-by: ncdiehl11 <[email protected]>
1 parent 78ac8fc commit f44872b

File tree

25 files changed

+432
-18
lines changed

25 files changed

+432
-18
lines changed

.eslintrc.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ module.exports = {
5252
'useLastRunCommandKey',
5353
'useCurrentMaintenanceRun',
5454
'useDeckConfigurationQuery',
55+
'useAllCommandsAsPreSerializedList',
5556
],
5657
message:
5758
'The HTTP hook is deprecated. Utilize the equivalent notification wrapper (useNotifyX) instead.',
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import { GET, request } from '../../request'
2+
3+
import type { ResponsePromise } from '../../request'
4+
import type { HostConfig } from '../../types'
5+
import type {
6+
CommandsAsPreSerializedListData,
7+
GetCommandsParams,
8+
} from './types'
9+
10+
export function getCommandsAsPreSerializedList(
11+
config: HostConfig,
12+
runId: string,
13+
params: GetCommandsParams
14+
): ResponsePromise<CommandsAsPreSerializedListData> {
15+
return request<CommandsAsPreSerializedListData>(
16+
GET,
17+
`/runs/${runId}/commandsAsPreSerializedList`,
18+
null,
19+
config,
20+
params
21+
)
22+
}

api-client/src/runs/commands/types.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,12 @@ export interface CommandsData {
3434
links: CommandsLinks
3535
}
3636

37+
export interface CommandsAsPreSerializedListData {
38+
data: string[]
39+
meta: GetCommandsParams & { totalLength: number }
40+
links: CommandsLinks
41+
}
42+
3743
export interface CreateCommandParams {
3844
waitUntilComplete?: boolean
3945
timeout?: number

api-client/src/runs/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ export { createCommand } from './commands/createCommand'
77
export { createLiveCommand } from './commands/createLiveCommand'
88
export { getCommand } from './commands/getCommand'
99
export { getCommands } from './commands/getCommands'
10+
export { getCommandsAsPreSerializedList } from './commands/getCommandsAsPreSerializedList'
1011
export { createRunAction } from './createRunAction'
1112
export * from './createLabwareOffset'
1213
export * from './createLabwareDefinition'

app/src/organisms/CommandText/LoadCommandText.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,9 @@ export const LoadCommandText = ({
131131
return null
132132
}
133133
} else {
134-
const labware = command.result?.definition.metadata.displayName
134+
const labware =
135+
command.result?.definition.metadata.displayName ??
136+
command.params.displayName
135137
return command.params.location === 'offDeck'
136138
? t('load_labware_info_protocol_setup_off_deck', { labware })
137139
: t('load_labware_info_protocol_setup_no_module', {

app/src/organisms/RunPreview/index.tsx

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ import { useTranslation } from 'react-i18next'
44
import { ViewportList, ViewportListRef } from 'react-viewport-list'
55

66
import { RUN_STATUSES_TERMINAL } from '@opentrons/api-client'
7-
import { useAllCommandsQuery } from '@opentrons/react-api-client'
87
import {
98
ALIGN_CENTER,
109
BORDERS,
@@ -21,7 +20,10 @@ import {
2120
} from '@opentrons/components'
2221

2322
import { useMostRecentCompletedAnalysis } from '../LabwarePositionCheck/useMostRecentCompletedAnalysis'
24-
import { useNotifyLastRunCommandKey } from '../../resources/runs'
23+
import {
24+
useNotifyAllCommandsAsPreSerializedList,
25+
useNotifyLastRunCommandKey,
26+
} from '../../resources/runs'
2527
import { CommandText } from '../CommandText'
2628
import { Divider } from '../../atoms/structure'
2729
import { NAV_BAR_WIDTH } from '../../App/constants'
@@ -33,6 +35,8 @@ import type { RobotType } from '@opentrons/shared-data'
3335

3436
const COLOR_FADE_MS = 500
3537
const LIVE_RUN_COMMANDS_POLL_MS = 3000
38+
// arbitrary large number of commands
39+
const MAX_COMMANDS = 100000
3640

3741
interface RunPreviewProps {
3842
runId: string
@@ -52,11 +56,17 @@ export const RunPreviewComponent = (
5256
? (RUN_STATUSES_TERMINAL as RunStatus[]).includes(runStatus)
5357
: false
5458
// we only ever want one request done for terminal runs because this is a heavy request
55-
const commandsFromQuery = useAllCommandsQuery(runId, null, {
56-
staleTime: Infinity,
57-
cacheTime: Infinity,
58-
enabled: isRunTerminal,
59-
}).data?.data
59+
const commandsFromQuery = useNotifyAllCommandsAsPreSerializedList(
60+
runId,
61+
{ cursor: 0, pageLength: MAX_COMMANDS },
62+
{
63+
staleTime: Infinity,
64+
cacheTime: Infinity,
65+
enabled: isRunTerminal,
66+
}
67+
).data?.data
68+
const nullCheckedCommandsFromQuery =
69+
commandsFromQuery == null ? robotSideAnalysis?.commands : commandsFromQuery
6070
const viewPortRef = React.useRef<HTMLDivElement | null>(null)
6171
const currentRunCommandKey = useNotifyLastRunCommandKey(runId, {
6272
refetchInterval: LIVE_RUN_COMMANDS_POLL_MS,
@@ -67,7 +77,9 @@ export const RunPreviewComponent = (
6777
] = React.useState<boolean>(true)
6878
if (robotSideAnalysis == null) return null
6979
const commands =
70-
(isRunTerminal ? commandsFromQuery : robotSideAnalysis.commands) ?? []
80+
(isRunTerminal
81+
? nullCheckedCommandsFromQuery
82+
: robotSideAnalysis.commands) ?? []
7183
const currentRunCommandIndex = commands.findIndex(
7284
c => c.key === currentRunCommandKey
7385
)

app/src/redux/shell/types.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,7 @@ export type NotifyTopic =
142142
| 'robot-server/runs'
143143
| `robot-server/runs/${string}`
144144
| 'robot-server/deck_configuration'
145+
| `robot-server/runs/pre_serialized_commands/${string}`
145146

146147
export interface NotifySubscribeAction {
147148
type: 'shell:NOTIFY_SUBSCRIBE'

app/src/resources/runs/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,4 @@ export * from './utils'
33
export * from './useNotifyAllRunsQuery'
44
export * from './useNotifyRunQuery'
55
export * from './useNotifyLastRunCommandKey'
6+
export * from './useNotifyAllCommandsAsPreSerializedList'
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import * as React from 'react'
2+
3+
import { useAllCommandsAsPreSerializedList } from '@opentrons/react-api-client'
4+
5+
import { useNotifyService } from '../useNotifyService'
6+
7+
import type { UseQueryResult } from 'react-query'
8+
import type { AxiosError } from 'axios'
9+
import type { CommandsData, GetCommandsParams } from '@opentrons/api-client'
10+
import type {
11+
QueryOptionsWithPolling,
12+
HTTPRefetchFrequency,
13+
} from '../useNotifyService'
14+
15+
export function useNotifyAllCommandsAsPreSerializedList(
16+
runId: string | null,
17+
params?: GetCommandsParams | null,
18+
options: QueryOptionsWithPolling<CommandsData, AxiosError> = {}
19+
): UseQueryResult<CommandsData, AxiosError> {
20+
const [refetch, setRefetch] = React.useState<HTTPRefetchFrequency>(null)
21+
22+
useNotifyService<CommandsData, AxiosError>({
23+
topic: `robot-server/runs/pre_serialized_commands/${runId}`,
24+
setRefetch,
25+
options,
26+
})
27+
28+
const httpResponse = useAllCommandsAsPreSerializedList(runId, params, {
29+
...options,
30+
enabled: options?.enabled !== false && refetch != null,
31+
onSettled: refetch === 'once' ? () => setRefetch(null) : () => null,
32+
})
33+
34+
return httpResponse
35+
}

react-api-client/src/runs/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ export { usePauseRunMutation } from './usePauseRunMutation'
1010
export { useStopRunMutation } from './useStopRunMutation'
1111
export { useRunActionMutations } from './useRunActionMutations'
1212
export { useAllCommandsQuery } from './useAllCommandsQuery'
13+
export { useAllCommandsAsPreSerializedList } from './useAllCommandsAsPreSerializedList'
1314
export { useCommandQuery } from './useCommandQuery'
1415
export * from './useCreateLabwareOffsetMutation'
1516
export * from './useCreateLabwareDefinitionMutation'

0 commit comments

Comments
 (0)