@@ -549,7 +549,6 @@ class Driver {
549549 } ;
550550 this . _info ( "User agent: " + navigator . userAgent ) ;
551551 this . _log ( `Harness thinks this browser is ${ this . browser } \n` ) ;
552- this . _log ( 'Fetching manifest "' + this . manifestFile + '"... ' ) ;
553552
554553 if ( this . delay > 0 ) {
555554 this . _log ( "\nDelaying for " + this . delay + " ms...\n" ) ;
@@ -562,32 +561,39 @@ class Driver {
562561 this . ws . addEventListener ( "open" , resolve , { once : true } ) ;
563562 } ) ;
564563 }
565- const response = await fetch ( this . manifestFile ) ;
566- if ( ! response . ok ) {
567- throw new Error ( response . statusText ) ;
568- }
569- this . _log ( "done\n" ) ;
570- this . manifest = await response . json ( ) ;
571564
572- if ( this . testFilter ?. length ) {
573- this . manifest = this . manifest . filter ( item => {
574- if ( this . testFilter . includes ( item . id ) ) {
575- return true ;
565+ // Dynamic task queue: server sends tasks on demand.
566+ this . taskQueue = [ ] ;
567+ this . serverDone = false ;
568+ this . pendingTaskResolve = null ;
569+ this . currentTask = null ;
570+ this . tasksDone = 0 ;
571+
572+ this . ws . addEventListener ( "message" , event => {
573+ if ( typeof event . data !== "string" ) {
574+ return ;
575+ }
576+ const msg = JSON . parse ( event . data ) ;
577+ if ( msg . type === "task" ) {
578+ if ( this . pendingTaskResolve ) {
579+ this . pendingTaskResolve ( msg . task ) ;
580+ this . pendingTaskResolve = null ;
581+ } else {
582+ this . taskQueue . push ( msg . task ) ;
583+ // Prefetch PDF for this task if it's now first in queue.
584+ if ( this . taskQueue . length === 1 ) {
585+ this . _prefetchNextTask ( ) ;
586+ }
576587 }
577- return false ;
578- } ) ;
579- }
580- if ( this . sessionCount > 1 ) {
581- const { sessionIndex, sessionCount } = this ;
582- const start = Math . floor (
583- ( this . manifest . length * sessionIndex ) / sessionCount
584- ) ;
585- const end = Math . floor (
586- ( this . manifest . length * ( sessionIndex + 1 ) ) / sessionCount
587- ) ;
588- this . manifest = this . manifest . slice ( start , end ) ;
589- }
590- this . currentTask = 0 ;
588+ } else if ( msg . type === "done" ) {
589+ this . serverDone = true ;
590+ if ( this . pendingTaskResolve ) {
591+ this . pendingTaskResolve ( null ) ;
592+ this . pendingTaskResolve = null ;
593+ }
594+ }
595+ } ) ;
596+
591597 this . _nextTask ( ) ;
592598 } , this . delay ) ;
593599 }
@@ -602,23 +608,38 @@ class Driver {
602608 */
603609 log ( msg ) {
604610 let id = this . browser ;
605- const task = this . manifest [ this . currentTask ] ;
606- if ( task ) {
607- id += `-${ task . id } ` ;
611+ if ( this . currentTask ) {
612+ id += `-${ this . currentTask . id } ` ;
608613 }
609-
610614 this . _info ( `${ id } : ${ msg } ` ) ;
611615 }
612616
617+ _waitForNextTask ( ) {
618+ if ( this . taskQueue . length > 0 ) {
619+ return Promise . resolve ( this . taskQueue . shift ( ) ) ;
620+ }
621+ if ( this . serverDone ) {
622+ return Promise . resolve ( null ) ;
623+ }
624+ this . ws . send (
625+ JSON . stringify ( { type : "requestTask" , browser : this . browser } )
626+ ) ;
627+ return new Promise ( resolve => {
628+ this . pendingTaskResolve = resolve ;
629+ } ) ;
630+ }
631+
613632 _nextTask ( ) {
614633 let failure = "" ;
615634
616- this . _cleanup ( ) . then ( ( ) => {
617- if ( this . currentTask === this . manifest . length ) {
635+ this . _cleanup ( ) . then ( async ( ) => {
636+ const task = await this . _waitForNextTask ( ) ;
637+ if ( ! task ) {
618638 this . _done ( ) ;
619639 return ;
620640 }
621- const task = this . manifest [ this . currentTask ] ;
641+ this . currentTask = task ;
642+
622643 task . round = 0 ;
623644 task . pageNum = task . firstPage || 1 ;
624645 task . stats = { times : [ ] } ;
@@ -658,13 +679,10 @@ class Driver {
658679 md5FileMap . set ( task . md5 , task . file ) ;
659680 }
660681
661- this . _log (
662- `[${ this . currentTask + 1 } /${ this . manifest . length } ] ${ task . id } :\n`
663- ) ;
682+ this . _log ( `[${ ++ this . tasksDone } ] ${ task . id } :\n` ) ;
664683
665684 if ( task . type === "skip-because-failing" ) {
666685 this . _log ( ` Skipping file "${ task . file } because it's failing"\n` ) ;
667- this . currentTask ++ ;
668686 this . _nextTask ( ) ;
669687 return ;
670688 }
@@ -678,7 +696,6 @@ class Driver {
678696 this . _nextPage ( task , 'Expected "other" test-case to be linked.' ) ;
679697 return ;
680698 }
681- this . currentTask ++ ;
682699 this . _nextTask ( ) ;
683700 return ;
684701 }
@@ -885,11 +902,10 @@ class Driver {
885902 }
886903
887904 _prefetchNextTask ( ) {
888- const nextIdx = this . currentTask + 1 ;
889- if ( nextIdx >= this . manifest . length ) {
905+ const task = this . taskQueue [ 0 ] ;
906+ if ( ! task ) {
890907 return ;
891908 }
892- const task = this . manifest [ nextIdx ] ;
893909 // Skip tasks that do not load a PDF or that need DOM setup (XFA style
894910 // element injection) to happen synchronously before getDocument.
895911 if (
@@ -899,7 +915,9 @@ class Driver {
899915 ) {
900916 return ;
901917 }
902- task . _prefetchedLoadingTask = getDocument ( this . _getDocumentOptions ( task ) ) ;
918+ if ( ! task . _prefetchedLoadingTask ) {
919+ task . _prefetchedLoadingTask = getDocument ( this . _getDocumentOptions ( task ) ) ;
920+ }
903921 }
904922
905923 _cleanup ( ) {
@@ -918,10 +936,10 @@ class Driver {
918936
919937 const destroyedPromises = [ ] ;
920938 // Wipe out the link to the pdfdoc so it can be GC'ed.
921- for ( let i = 0 ; i < this . manifest . length ; i ++ ) {
922- if ( this . manifest [ i ] . pdfDoc ) {
923- destroyedPromises . push ( this . manifest [ i ] . pdfDoc . destroy ( ) ) ;
924- delete this . manifest [ i ] . pdfDoc ;
939+ for ( const task of [ this . currentTask , ... this . taskQueue ] ) {
940+ if ( task ? .pdfDoc ) {
941+ destroyedPromises . push ( task . pdfDoc . destroy ( ) ) ;
942+ delete task . pdfDoc ;
925943 }
926944 }
927945 return Promise . all ( destroyedPromises ) ;
@@ -955,7 +973,6 @@ class Driver {
955973 . then ( blob => this . _sendResult ( blob , task , failure ) )
956974 . then ( ( ) => {
957975 this . _log ( `done${ failure ? ` (failed !: ${ failure } )` : "" } \n` ) ;
958- this . currentTask ++ ;
959976 this . _nextTask ( ) ;
960977 } ) ;
961978 return ;
@@ -966,7 +983,6 @@ class Driver {
966983 this . _log ( ` Round ${ 1 + task . round } \n` ) ;
967984 task . pageNum = task . firstPage || 1 ;
968985 } else {
969- this . currentTask ++ ;
970986 this . _nextTask ( ) ;
971987 return ;
972988 }
0 commit comments