@@ -121,12 +121,37 @@ qx.Class.define("osparc.jobs.RunsTableModel", {
121121
122122 // overridden
123123 _loadRowData ( firstRow , qxLastRow ) {
124+ console . info ( `🔄 _loadRowData requested: firstRow=${ firstRow } , qxLastRow=${ qxLastRow } ` ) ;
125+
126+ // Prevent multiple simultaneous requests
127+ if ( this . getIsFetching ( ) ) {
128+ console . info ( `⏳ Already fetching data, queuing request for ${ firstRow } -${ qxLastRow } ` ) ;
129+ setTimeout ( ( ) => this . _loadRowData ( firstRow , qxLastRow ) , 100 ) ;
130+ return ;
131+ }
132+
133+ // Limit the request to smaller chunks for better pagination
134+ const PAGE_SIZE = 20 ;
135+ const nextChunkStart = this . __findNextSequentialChunk ( firstRow ) ;
136+ const lastRow = Math . min ( nextChunkStart + PAGE_SIZE - 1 , this . _rowCount - 1 ) ;
137+
138+ console . info ( `📏 Loading sequential chunk: ${ nextChunkStart } -${ lastRow } (requested: ${ firstRow } -${ qxLastRow } )` ) ;
139+
140+ // Check if we already have all the requested data cached
141+ const cachedData = this . __getCachedDataForRange ( firstRow , Math . min ( qxLastRow , lastRow ) ) ;
142+ if ( cachedData . length === ( Math . min ( qxLastRow , lastRow ) - firstRow + 1 ) ) {
143+ console . info ( `✅ All data cached for range ${ firstRow } -${ Math . min ( qxLastRow , lastRow ) } , returning cached data` ) ;
144+ this . _onRowDataLoaded ( cachedData ) ;
145+ return ;
146+ }
147+
148+ const missingRanges = [ { start : nextChunkStart , end : lastRow } ] ;
149+ console . info ( `📡 Loading next sequential chunk:` , missingRanges ) ;
150+
124151 this . setIsFetching ( true ) ;
125152
126- const lastRow = Math . min ( qxLastRow , this . _rowCount - 1 ) ;
127- // Returns a request promise with given offset and limit
128153 const getFetchPromise = ( offset , limit ) => {
129- const orderBy = this . getOrderBy ( ) ;
154+ const orderBy = this . getOrderBy ( ) ;
130155 let promise ;
131156 if ( this . getProjectUuid ( ) ) {
132157 promise = osparc . store . Jobs . getInstance ( ) . fetchJobsHistory ( this . getProjectUuid ( ) , this . __includeChildren , offset , limit , orderBy ) ;
@@ -152,33 +177,73 @@ qx.Class.define("osparc.jobs.RunsTableModel", {
152177 } ) ;
153178 } ;
154179
155- // Divides the model row request into several server requests to comply with the number of rows server limit
156- const reqLimit = lastRow - firstRow + 1 ; // Number of requested rows
157- const serverMaxLimit = osparc . store . Jobs . SERVER_MAX_LIMIT ;
158- let nRequests = Math . ceil ( reqLimit / serverMaxLimit ) ;
159- if ( nRequests > 1 ) {
160- const requests = [ ] ;
161- for ( let i = firstRow ; i <= lastRow ; i += serverMaxLimit ) {
162- requests . push ( getFetchPromise ( i , i > lastRow - serverMaxLimit + 1 ? reqLimit % serverMaxLimit : serverMaxLimit ) )
180+ const fetchPromises = missingRanges . map ( range => {
181+ const rangeSize = range . end - range . start + 1 ;
182+ const serverMaxLimit = osparc . store . Jobs . SERVER_MAX_LIMIT ;
183+
184+ if ( rangeSize <= serverMaxLimit ) {
185+ return getFetchPromise ( range . start , rangeSize ) . then ( data => ( {
186+ start : range . start ,
187+ data : data
188+ } ) ) ;
189+ } else {
190+ const requests = [ ] ;
191+ for ( let i = range . start ; i <= range . end ; i += serverMaxLimit ) {
192+ const chunkSize = Math . min ( serverMaxLimit , range . end - i + 1 ) ;
193+ requests . push ( getFetchPromise ( i , chunkSize ) . then ( data => ( {
194+ start : i ,
195+ data : data
196+ } ) ) ) ;
197+ }
198+ return Promise . all ( requests ) . then ( chunks => ( {
199+ start : range . start ,
200+ data : chunks . flatMap ( chunk => chunk . data )
201+ } ) ) ;
202+ }
203+ } ) ;
204+
205+ Promise . all ( fetchPromises )
206+ . then ( fetchedRanges => {
207+ fetchedRanges . forEach ( fetchedRange => {
208+ fetchedRange . data . forEach ( ( rowData , index ) => {
209+ this . __cachedData . set ( fetchedRange . start + index , rowData ) ;
210+ } ) ;
211+ this . __loadedRanges . push ( { start : fetchedRange . start , end : fetchedRange . start + fetchedRange . data . length - 1 } ) ;
212+ } ) ;
213+
214+ const requestedData = this . __getCachedDataForRange ( firstRow , lastRow ) ;
215+ this . _onRowDataLoaded ( requestedData ) ;
216+ } )
217+ . catch ( err => {
218+ console . error ( err ) ;
219+ this . _onRowDataLoaded ( null ) ;
220+ } )
221+ . finally ( ( ) => this . setIsFetching ( false ) ) ;
222+ } ,
223+
224+ __findNextSequentialChunk : function ( requestedStart ) {
225+ let consecutiveEnd = - 1 ;
226+ for ( let i = 0 ; i < this . _rowCount ; i ++ ) {
227+ if ( this . __cachedData . has ( i ) ) {
228+ consecutiveEnd = i ;
229+ } else {
230+ break ;
163231 }
164- Promise . all ( requests )
165- . then ( responses => this . _onRowDataLoaded ( responses . flat ( ) ) )
166- . catch ( err => {
167- console . error ( err ) ;
168- this . _onRowDataLoaded ( null ) ;
169- } )
170- . finally ( ( ) => this . setIsFetching ( false ) ) ;
171- } else {
172- getFetchPromise ( firstRow , reqLimit )
173- . then ( data => {
174- this . _onRowDataLoaded ( data ) ;
175- } )
176- . catch ( err => {
177- console . error ( err )
178- this . _onRowDataLoaded ( null ) ;
179- } )
180- . finally ( ( ) => this . setIsFetching ( false ) ) ;
181232 }
182- }
233+
234+ const nextStart = consecutiveEnd + 1 ;
235+ console . info ( `📍 Consecutive data ends at row ${ consecutiveEnd } , next chunk starts at ${ nextStart } ` ) ;
236+ return Math . max ( nextStart , 0 ) ;
237+ } ,
238+
239+ __getCachedDataForRange : function ( firstRow , lastRow ) {
240+ const data = [ ] ;
241+ for ( let i = firstRow ; i <= lastRow ; i ++ ) {
242+ if ( this . __cachedData . has ( i ) ) {
243+ data . push ( this . __cachedData . get ( i ) ) ;
244+ }
245+ }
246+ return data ;
247+ } ,
183248 }
184249} )
0 commit comments