@@ -53,8 +53,9 @@ logScope:
5353 topics = " codex node"
5454
5555const
56- DefaultFetchBatch = 2048
56+ DefaultFetchBatch = 1024
5757 MaxOnBatchBlocks = 128
58+ BatchRefillThreshold = 0.75 # Refill when 75% of window completes
5859
5960type
6061 Contracts * =
@@ -188,48 +189,61 @@ proc fetchBatched*(
188189 # (i: int) => self.networkStore.getBlock(BlockAddress.init(cid, i))
189190 # )
190191
191- var addresses = newSeqOfCap [BlockAddress ](batchSize)
192- while not iter.finished:
193- addresses.setLen (0 )
194- for i in 0 ..< batchSize:
195- if not iter.finished:
196- let address = BlockAddress .init (cid, iter.next ())
197- if fetchLocal or not (await address in self.networkStore):
198- addresses.add (address)
199-
200- let blockResults = await self.networkStore.getBlocks (addresses)
201-
202- var
203- successfulBlocks = 0
204- failedBlocks = 0
205- blockData: seq [bt.Block ]
206-
207- for res in blockResults:
208- without blk =? await res:
209- inc (failedBlocks)
210- continue
211-
212- inc (successfulBlocks)
213-
214- # Only retains block data in memory if there's
215- # a callback.
216- if not onBatch.isNil:
217- blockData.add (blk)
218-
219- if blockData.len >= MaxOnBatchBlocks :
220- if batchErr =? (await onBatch (blockData)).errorOption:
221- return failure (batchErr)
222- blockData = @ []
223-
224- if failedBlocks > 0 :
225- return failure (" Some blocks failed (Result) to fetch (" & $ failedBlocks & " )" )
192+ # Sliding window: maintain batchSize blocks in-flight
193+ let
194+ refillThreshold = int (float (batchSize) * BatchRefillThreshold )
195+ refillSize = max (refillThreshold, 1 )
196+ maxCallbackBlocks = min (batchSize, MaxOnBatchBlocks )
226197
227- if not onBatch.isNil and blockData.len > 0 :
228- if batchErr =? (await onBatch (blockData)).errorOption:
229- return failure (batchErr)
198+ var
199+ blockData: seq [bt.Block ]
200+ failedBlocks = 0
201+ successfulBlocks = 0
202+ completedInWindow = 0
230203
204+ var addresses = newSeqOfCap [BlockAddress ](batchSize)
205+ for i in 0 ..< batchSize:
231206 if not iter.finished:
232- await idleAsync ()
207+ let address = BlockAddress .init (cid, iter.next ())
208+ if fetchLocal or not (await address in self.networkStore):
209+ addresses.add (address)
210+
211+ var blockResults = await self.networkStore.getBlocks (addresses)
212+
213+ while not blockResults.finished:
214+ without blk =? await blockResults.next (), err:
215+ inc (failedBlocks)
216+ continue
217+
218+ inc (successfulBlocks)
219+ inc (completedInWindow)
220+
221+ if not onBatch.isNil:
222+ blockData.add (blk)
223+ if blockData.len >= maxCallbackBlocks:
224+ if batchErr =? (await onBatch (blockData)).errorOption:
225+ return failure (batchErr)
226+ blockData = @ []
227+
228+ if completedInWindow >= refillThreshold and not iter.finished:
229+ var refillAddresses = newSeqOfCap [BlockAddress ](refillSize)
230+ for i in 0 ..< refillSize:
231+ if not iter.finished:
232+ let address = BlockAddress .init (cid, iter.next ())
233+ if fetchLocal or not (await address in self.networkStore):
234+ refillAddresses.add (address)
235+
236+ if refillAddresses.len > 0 :
237+ blockResults =
238+ chain (blockResults, await self.networkStore.getBlocks (refillAddresses))
239+ completedInWindow = 0
240+
241+ if failedBlocks > 0 :
242+ return failure (" Some blocks failed (Result) to fetch (" & $ failedBlocks & " )" )
243+
244+ if not onBatch.isNil and blockData.len > 0 :
245+ if batchErr =? (await onBatch (blockData)).errorOption:
246+ return failure (batchErr)
233247
234248 success ()
235249
0 commit comments