@@ -25,7 +25,8 @@ import {
2525} from './workflow-server-actions' ;
2626
2727const MAX_ITEMS = 1000 ;
28- const LIVE_POLL_LIMIT = 5 ;
28+ const LIVE_POLL_LIMIT = 10 ;
29+ const LIVE_STEP_UPDATE_INTERVAL_MS = 2000 ;
2930const LIVE_UPDATE_INTERVAL_MS = 5000 ;
3031
3132/**
@@ -660,6 +661,7 @@ export function useWorkflowTraceViewerData(
660661 const [ hooks , setHooks ] = useState < Hook [ ] > ( [ ] ) ;
661662 const [ events , setEvents ] = useState < Event [ ] > ( [ ] ) ;
662663 const [ loading , setLoading ] = useState ( true ) ;
664+ const [ auxiliaryDataLoading , setAuxiliaryDataLoading ] = useState ( false ) ;
663665 const [ error , setError ] = useState < Error | null > ( null ) ;
664666
665667 const [ stepsCursor , setStepsCursor ] = useState < string | undefined > ( ) ;
@@ -677,29 +679,33 @@ export function useWorkflowTraceViewerData(
677679
678680 isFetchingRef . current = true ;
679681 setLoading ( true ) ;
682+ setAuxiliaryDataLoading ( true ) ;
680683 setError ( null ) ;
681684
685+ const promises = [
686+ fetchRun ( env , runId ) . then ( ( result ) => {
687+ // The run is the most visible part - so we can start showing UI
688+ // as soon as we have the run
689+ setLoading ( false ) ;
690+ setRun ( unwrapServerActionResult ( result ) ) ;
691+ } ) ,
692+ fetchAllSteps ( env , runId ) . then ( ( result ) => {
693+ setSteps ( result . data ) ;
694+ setStepsCursor ( result . cursor ) ;
695+ } ) ,
696+ fetchAllHooks ( env , runId ) . then ( ( result ) => {
697+ setHooks ( result . data ) ;
698+ setHooksCursor ( result . cursor ) ;
699+ } ) ,
700+ fetchAllEvents ( env , runId ) . then ( ( result ) => {
701+ setEvents ( result . data ) ;
702+ setEventsCursor ( result . cursor ) ;
703+ } ) ,
704+ ] ;
705+
682706 try {
683707 // Fetch run
684- const runServerResult = await fetchRun ( env , runId ) ;
685- const runData = unwrapServerActionResult ( runServerResult ) ;
686- setRun ( runData ) ;
687-
688- // TODO: Do these in parallel
689- // Fetch steps exhaustively
690- const stepsResult = await fetchAllSteps ( env , runId ) ;
691- setSteps ( stepsResult . data ) ;
692- setStepsCursor ( stepsResult . cursor ) ;
693-
694- // Fetch hooks exhaustively
695- const hooksResult = await fetchAllHooks ( env , runId ) ;
696- setHooks ( hooksResult . data ) ;
697- setHooksCursor ( hooksResult . cursor ) ;
698-
699- // Fetch events exhaustively
700- const eventsResult = await fetchAllEvents ( env , runId ) ;
701- setEvents ( eventsResult . data ) ;
702- setEventsCursor ( eventsResult . cursor ) ;
708+ await Promise . all ( promises ) ;
703709 } catch ( err ) {
704710 const error =
705711 err instanceof WorkflowAPIError
@@ -711,6 +717,7 @@ export function useWorkflowTraceViewerData(
711717 setError ( error ) ;
712718 } finally {
713719 setLoading ( false ) ;
720+ setAuxiliaryDataLoading ( false ) ;
714721 isFetchingRef . current = false ;
715722 setInitialLoadCompleted ( true ) ;
716723 }
@@ -808,27 +815,31 @@ export function useWorkflowTraceViewerData(
808815 } , [ env , runId , eventsCursor , mergeEvents ] ) ;
809816
810817 // Update function for live polling
811- const update = useCallback ( async ( ) : Promise < { foundNewItems : boolean } > => {
812- if ( isFetchingRef . current || ! initialLoadCompleted ) {
813- return { foundNewItems : false } ;
814- }
818+ const update = useCallback (
819+ async ( stepsOnly : boolean = false ) : Promise < { foundNewItems : boolean } > => {
820+ if ( isFetchingRef . current || ! initialLoadCompleted ) {
821+ return { foundNewItems : false } ;
822+ }
815823
816- let foundNewItems = false ;
824+ let foundNewItems = false ;
817825
818- try {
819- const [ _ , stepsUpdated , hooksUpdated , eventsUpdated ] = await Promise . all ( [
820- pollRun ( ) ,
821- pollSteps ( ) ,
822- pollHooks ( ) ,
823- pollEvents ( ) ,
824- ] ) ;
825- foundNewItems = stepsUpdated || hooksUpdated || eventsUpdated ;
826- } catch ( err ) {
827- console . error ( 'Update error:' , err ) ;
828- }
826+ try {
827+ const [ _ , stepsUpdated , hooksUpdated , eventsUpdated ] =
828+ await Promise . all ( [
829+ stepsOnly ? Promise . resolve ( false ) : pollRun ( ) ,
830+ pollSteps ( ) ,
831+ stepsOnly ? Promise . resolve ( false ) : pollHooks ( ) ,
832+ stepsOnly ? Promise . resolve ( false ) : pollEvents ( ) ,
833+ ] ) ;
834+ foundNewItems = stepsUpdated || hooksUpdated || eventsUpdated ;
835+ } catch ( err ) {
836+ console . error ( 'Update error:' , err ) ;
837+ }
829838
830- return { foundNewItems } ;
831- } , [ pollSteps , pollHooks , pollEvents , initialLoadCompleted , pollRun ] ) ;
839+ return { foundNewItems } ;
840+ } ,
841+ [ pollSteps , pollHooks , pollEvents , initialLoadCompleted , pollRun ]
842+ ) ;
832843
833844 // Initial load
834845 useEffect ( ( ) => {
@@ -844,8 +855,14 @@ export function useWorkflowTraceViewerData(
844855 const interval = setInterval ( ( ) => {
845856 update ( ) ;
846857 } , LIVE_UPDATE_INTERVAL_MS ) ;
847-
848- return ( ) => clearInterval ( interval ) ;
858+ const stepInterval = setInterval ( ( ) => {
859+ update ( true ) ;
860+ } , LIVE_STEP_UPDATE_INTERVAL_MS ) ;
861+
862+ return ( ) => {
863+ clearInterval ( interval ) ;
864+ clearInterval ( stepInterval ) ;
865+ } ;
849866 } , [ live , initialLoadCompleted , update , run ?. completedAt ] ) ;
850867
851868 return {
@@ -854,6 +871,7 @@ export function useWorkflowTraceViewerData(
854871 hooks,
855872 events,
856873 loading,
874+ auxiliaryDataLoading,
857875 error,
858876 update,
859877 } ;
0 commit comments