@@ -60,18 +60,48 @@ const buildInferenceMetadata = ({ types }) =>
6060 // TODO: use async iterators when we switch to node>=10
6161 // or better investigate if we can offload metadata building to worker/Jobs API
6262 // and then feed the result into redux?
63- const processNextType = ( ) => {
63+ const processNextType = async ( ) => {
6464 const typeName = typeNames . pop ( )
65- store . dispatch ( {
66- type : `BUILD_TYPE_METADATA` ,
67- payload : {
68- typeName,
69- nodes : getDataStore ( ) . iterateNodesByType ( typeName ) ,
70- } ,
71- } )
65+
66+ let processingNodes = [ ]
67+ let dispatchCount = 0
68+ function dispatchNodes ( ) {
69+ return new Promise ( res => {
70+ store . dispatch ( {
71+ type : `BUILD_TYPE_METADATA` ,
72+ payload : {
73+ typeName,
74+ // only clear metadata on the first chunk for this type
75+ clearExistingMetadata : dispatchCount ++ === 0 ,
76+ nodes : processingNodes ,
77+ } ,
78+ } )
79+ setImmediate ( ( ) => {
80+ // clear this array after BUILD_TYPE_METADATA reducer has synchronously run
81+ processingNodes = [ ]
82+ // dont block the event loop. node may decide to free previous processingNodes array from memory if it needs to.
83+ setImmediate ( ( ) => {
84+ res ( null )
85+ } )
86+ } )
87+ } )
88+ }
89+
90+ for ( const node of getDataStore ( ) . iterateNodesByType ( typeName ) ) {
91+ processingNodes . push ( node )
92+
93+ if ( processingNodes . length > 1000 ) {
94+ await dispatchNodes ( )
95+ }
96+ }
97+
98+ if ( processingNodes . length > 0 ) {
99+ await dispatchNodes ( )
100+ }
101+
72102 if ( typeNames . length > 0 ) {
73- // Give event-loop a break
74- setTimeout ( processNextType , 0 )
103+ // dont block the event loop
104+ setImmediate ( ( ) => processNextType ( ) )
75105 } else {
76106 resolve ( )
77107 }
0 commit comments