fix multiple event streams bug and only open logs stream if step open (#525)

This commit is contained in:
Dan Wilson 2023-09-18 16:01:45 +00:00 committed by Harness
parent ebe2800101
commit cd6e800075
8 changed files with 110 additions and 42 deletions

View File

@ -40,7 +40,7 @@ const ConsoleStep: FC<ConsoleStepProps> = ({ step, stageNumber, repoPath, pipeli
}, [stageNumber])
useEffect(() => {
if (step?.status === ExecutionState.RUNNING) {
if (step?.status === ExecutionState.RUNNING && isOpened) {
if (eventSourceRef.current) {
eventSourceRef.current.close()
setStreamingLogs([])
@ -64,6 +64,7 @@ const ConsoleStep: FC<ConsoleStepProps> = ({ step, stageNumber, repoPath, pipeli
setStreamingLogs([])
if (eventSourceRef.current) eventSourceRef.current.close()
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [executionNumber, isOpened, pipelineName, repoPath, stageNumber, step?.name, step?.number, step?.status])
let icon

View File

@ -10,3 +10,11 @@
.withError {
display: grid;
}
.error {
top: 0 !important;
background-color: var(--red) !important;
height: var(--log-content-header-height) !important;
padding: var(--spacing-medium) !important;
font-weight: 600 !important;
}

View File

@ -1,5 +1,6 @@
/* eslint-disable */
// This is an auto-generated file
export declare const error: string
export declare const main: string
export declare const pageBody: string
export declare const withError: string

View File

@ -1,8 +1,9 @@
import { Container, PageBody } from '@harnessio/uicore'
import React, { useEffect, useState } from 'react'
import { Container, PageBody, Text } from '@harnessio/uicore'
import React, { useCallback, useEffect, useMemo, useState } from 'react'
import cx from 'classnames'
import { useParams } from 'react-router-dom'
import { useGet } from 'restful-react'
import { Color, FontVariation } from '@harnessio/design-system'
import { routes, type CODEProps } from 'RouteDefinitions'
import type { TypesExecution } from 'services/code'
import ExecutionStageList from 'components/ExecutionStageList/ExecutionStageList'
@ -46,10 +47,8 @@ const Execution = () => {
}
}, [execution])
useSpaceSSE({
space,
events: ['execution_updated', 'execution_completed', 'execution_canceled', 'execution_running'],
onEvent: data => {
const onEvent = useCallback(
data => {
if (
data?.repo_id === execution?.repo_id &&
data?.pipeline_id === execution?.pipeline_id &&
@ -59,7 +58,24 @@ const Execution = () => {
executionRefetch()
}
},
shouldRun: [ExecutionState.RUNNING, ExecutionState.PENDING].includes(getStatus(execution?.status))
// eslint-disable-next-line react-hooks/exhaustive-deps
[execution?.number, execution?.pipeline_id, execution?.repo_id]
)
const shouldRun = useMemo(() => {
return [ExecutionState.RUNNING, ExecutionState.PENDING].includes(getStatus(execution?.status))
}, [execution?.status])
const events = useMemo(
() => ['execution_updated', 'execution_completed', 'execution_canceled', 'execution_running'],
[]
)
useSpaceSSE({
space,
events,
onEvent,
shouldRun
})
return (
@ -102,7 +118,14 @@ const Execution = () => {
// button: NewExecutionButton
}}>
<LoadingSpinner visible={loading || isInitialLoad} withBorder={!!execution && isInitialLoad} />
{execution && (
{execution?.error && (
<Container className={css.error}>
<Text font={{ variation: FontVariation.BODY }} color={Color.WHITE}>
{execution?.error}
</Text>
</Container>
)}
{execution && !execution?.error && (
<Split split="vertical" size={300} minSize={200} maxSize={400}>
<ExecutionStageList
stages={execution?.stages || []}

View File

@ -1,4 +1,4 @@
import React, { useEffect, useMemo, useState } from 'react'
import React, { useCallback, useEffect, useMemo, useState } from 'react'
import {
Button,
ButtonVariation,
@ -22,7 +22,7 @@ import { useAppContext } from 'AppContext'
import { NoResultCard } from 'components/NoResultCard/NoResultCard'
import { LIST_FETCHING_LIMIT, PageBrowserProps, getErrorMessage, timeDistance, voidFn } from 'utils/Utils'
import type { CODEProps } from 'RouteDefinitions'
import type { EnumTriggerAction, TypesExecution } from 'services/code'
import type { EnumTriggerAction, TypesExecution, TypesPipeline } from 'services/code'
import { useQueryParams } from 'hooks/useQueryParams'
import { usePageIndex } from 'hooks/usePageIndex'
import { ResourceListingPagination } from 'components/ResourceListingPagination/ResourceListingPagination'
@ -49,6 +49,11 @@ const ExecutionList = () => {
const { repoMetadata, error, loading, refetch, space } = useGetRepositoryMetadata()
const { data: pipelineData, error: pipelineError } = useGet<TypesPipeline>({
path: `/api/v1/repos/${repoMetadata?.path}/+/pipelines/${pipeline}`,
lazy: !repoMetadata
})
const {
data: executions,
error: executionsError,
@ -69,20 +74,27 @@ const ExecutionList = () => {
}
}, [executions])
useSpaceSSE({
space,
events: ['execution_updated', 'execution_completed', 'execution_canceled', 'execution_running'],
onEvent: data => {
const onEvent = useCallback(
data => {
// ideally this would include number - so we only check for executions on the page - but what if new executions are kicked off? - could check for ids that are higher than the lowest id on the page?
if (
executions?.some(
execution => execution.repo_id === data?.repo_id && execution.pipeline_id === data?.pipeline_id
)
) {
if (repoMetadata?.id === data?.repo_id && pipelineData?.id === data?.pipeline_id) {
//TODO - revisit full refresh - can I use the message to update the execution?
executionsRefetch()
}
}
},
// eslint-disable-next-line react-hooks/exhaustive-deps
[pipelineData?.id, repoMetadata?.id]
)
const events = useMemo(
() => ['execution_updated', 'execution_completed', 'execution_canceled', 'execution_running'],
[]
)
useSpaceSSE({
space,
events,
onEvent
})
const { openModal: openRunPipelineModal } = useRunPipelineModal()
@ -183,8 +195,8 @@ const ExecutionList = () => {
}
/>
<PageBody
className={cx({ [css.withError]: !!error })}
error={error ? getErrorMessage(error || executionsError) : null}
className={cx({ [css.withError]: !!error || !!pipelineError || !!executionsError })}
error={error || pipeline || executionsError ? getErrorMessage(error || pipelineError || executionsError) : null}
retryOnError={voidFn(refetch)}
noData={{
when: () => executions?.length === 0,

View File

@ -1,4 +1,4 @@
import React, { useEffect, useMemo, useState } from 'react'
import React, { useCallback, useEffect, useMemo, useState } from 'react'
import { Classes, Intent, Menu, MenuItem, Popover, Position } from '@blueprintjs/core'
import {
Avatar,
@ -78,16 +78,27 @@ const PipelineList = () => {
}
}, [pipelines])
useSpaceSSE({
space,
events: ['execution_updated', 'execution_completed', 'execution_canceled', 'execution_running'],
onEvent: data => {
// should I include pipeline id here? what if a new pipeline is created? coould check for ids that are higher than the lowest id on the page?
if (pipelines?.some(pipeline => pipeline.repo_id === data?.repo_id && pipeline.id === data?.pipeline_id)) {
//TODO - revisit full refresh - can I use the message to update the execution?
const onEvent = useCallback(
data => {
// should I include pipeline id here? what if a new pipeline is created? could check for ids that are higher than the lowest id on the page?
if (repoMetadata?.id === data?.repo_id) {
//TODO - revisit full refresh - can I use the message to update the pipeline?
pipelinesRefetch()
}
}
},
// eslint-disable-next-line react-hooks/exhaustive-deps
[repoMetadata?.id]
)
const events = useMemo(
() => ['execution_updated', 'execution_completed', 'execution_canceled', 'execution_running'],
[]
)
useSpaceSSE({
space,
events,
onEvent
})
const NewPipelineButton = (
@ -300,6 +311,7 @@ const PipelineList = () => {
}
}
],
// eslint-disable-next-line react-hooks/exhaustive-deps
[getString, history, repoMetadata?.path, routes, searchTerm]
)
@ -311,7 +323,7 @@ const PipelineList = () => {
dataTooltipId="repositoryPipelines"
/>
<PageBody
className={cx({ [css.withError]: !!error })}
className={cx({ [css.withError]: !!error || !!pipelinesError })}
error={error || pipelinesError ? getErrorMessage(error || pipelinesError) : null}
retryOnError={voidFn(refetch)}
noData={{

View File

@ -61,16 +61,25 @@ export default function RepositoriesListing() {
queryParams: { page, limit: LIST_FETCHING_LIMIT, query: searchTerm },
debounce: 500
})
useSpaceSSE({
space,
events: ['repository_import_completed'],
onEvent: data => {
// should I include pipeline id here? what if a new pipeline is created? coould check for ids that are higher than the lowest id on the page?
const onEvent = useCallback(
data => {
// should I include repo id here? what if a new repo is created? coould check for ids that are higher than the lowest id on the page?
if (repositories?.some(repository => repository.id === data?.id && repository.parent_id === data?.parent_id)) {
//TODO - revisit full refresh - can I use the message to update the execution?
refetch()
}
}
// eslint-disable-next-line react-hooks/exhaustive-deps
},
[repositories]
)
const events = useMemo(() => ['repository_import_completed'], [])
useSpaceSSE({
space,
events,
onEvent
})
useEffect(() => {

View File

@ -1,4 +1,4 @@
import React, { useEffect, useState } from 'react'
import React, { useEffect, useMemo, useState } from 'react'
import {
Button,
Text,
@ -18,8 +18,8 @@ import { useMutate, useGet } from 'restful-react'
import { Intent, Color, FontVariation } from '@harnessio/design-system'
import { useHistory } from 'react-router-dom'
import { Dialog } from '@blueprintjs/core'
import { useGetRepositoryMetadata } from 'hooks/useGetRepositoryMetadata'
import { ProgressBar, Intent as IntentCore } from '@blueprintjs/core'
import { useGetRepositoryMetadata } from 'hooks/useGetRepositoryMetadata'
import { TypesJobProgress, useGetSpace } from 'services/code'
import { useAppContext } from 'AppContext'
import { useStrings } from 'framework/strings'
@ -86,9 +86,11 @@ export default function SpaceSettings() {
}
}, [exportProgressSpace, checkExportIsRunning, checkReposState, countFinishedRepos])
const events = useMemo(() => ['repository_export_completed'], [])
useSpaceSSE({
space,
events: ['repository_export_completed'],
events,
onEvent: () => {
refetchExport()