55 * provider machine and returns ready-to-commit `pieceCid`s.
66 */
77
8+ import fs from 'node:fs/promises'
9+ import path from 'node:path'
10+
811import { parse as parsePieceCid } from '@filoz/synapse-core/piece'
912import { fromSecp256k1 } from '@filoz/synapse-core/session-key'
1013import { addPieces , createDataSet , waitForAddPieces , waitForCreateDataSet } from '@filoz/synapse-core/sp'
@@ -16,7 +19,7 @@ import { getAddress } from 'viem/utils'
1619import { z } from 'zod'
1720
1821import { renderProgressLine } from '../../utils.js'
19- import { shardsDir } from '../lib/layout.mjs'
22+ import { parkingResultsDir , shardsDir } from '../lib/layout.mjs'
2023import { openTrackingDb } from '../lib/tracking-db.mjs'
2124
2225const PARKING_BATCH_SIZE = 50
@@ -155,6 +158,7 @@ function renderCommitProgress(summary) {
155158 * @typedef {object } ParkingResult
156159 * @property {number } count
157160 * @property {string[] } pieces
161+ * @property {string | null } error
158162 */
159163
160164const parkingResultSchema = z
@@ -164,29 +168,18 @@ const parkingResultSchema = z
164168 . array ( z . string ( ) )
165169 . nullable ( )
166170 . transform ( ( pieces ) => pieces ?? [ ] ) ,
171+ error : z
172+ . string ( )
173+ . nullable ( )
174+ . optional ( )
175+ . transform ( ( error ) => error ?? null ) ,
167176 } )
168177 . refine ( ( value ) => value . count === value . pieces . length , {
169178 message : 'count must match pieces length' ,
170179 } )
171180
172- /**
173- * Curio may emit log lines before the final JSON result.
174- *
175- * @param {string } stdout
176- */
177- function extractParkingJson ( stdout ) {
178- const trimmed = stdout . trim ( )
179- if ( ! trimmed ) {
180- throw new Error ( 'commit: parking command returned empty stdout' )
181- }
182-
183- const objectStart = trimmed . lastIndexOf ( '\n{' )
184- const start = objectStart >= 0 ? objectStart + 1 : trimmed . indexOf ( '{' )
185- if ( start < 0 ) {
186- throw new Error ( 'commit: parking command returned no JSON result in stdout' )
187- }
188-
189- return trimmed . slice ( start )
181+ function formatParkingResultTimestamp ( ) {
182+ return new Date ( ) . toISOString ( ) . replaceAll ( ':' , '-' )
190183}
191184
192185/**
@@ -195,9 +188,14 @@ function extractParkingJson(stdout) {
195188 * @returns {Promise<ParkingResult> }
196189 */
197190async function runParkingBinary ( dir , target ) {
198- let result
191+ const resultsDir = parkingResultsDir ( dir )
192+ await fs . mkdir ( resultsDir , { recursive : true } )
193+
194+ const resultPath = path . join ( resultsDir , `parking-result-${ formatParkingResultTimestamp ( ) } .json` )
195+ /** @type {string | null } */
196+ let commandError = null
199197 try {
200- result = await execa ( {
198+ await execa ( {
201199 env : {
202200 LANG : 'en_US.UTF-8' ,
203201 GOLOG_LOG_LEVEL : 'error' ,
@@ -209,22 +207,34 @@ async function runParkingBinary(dir, target) {
209207 shardsDir ( dir ) ,
210208 '--target' ,
211209 target ,
210+ '--result' ,
211+ resultPath ,
212212 '--batch-size' ,
213213 String ( PARKING_BATCH_SIZE ) ,
214214 ] )
215215 } catch ( err ) {
216- const message = err ?. stderr || err ?. stdout || err ?. message || String ( err )
217- throw new Error ( `commit: parking command failed: ${ message } ` )
216+ commandError = err ?. stderr || err ?. stdout || err ?. message || String ( err )
218217 }
219218
220219 let parsed
221220 try {
222- parsed = JSON . parse ( extractParkingJson ( result . stdout || '' ) )
221+ const content = await fs . readFile ( resultPath , 'utf8' )
222+ parsed = JSON . parse ( content )
223223 } catch ( err ) {
224- throw new Error ( `commit: parking command returned invalid JSON : ${ err ?. message || err } ` )
224+ throw new Error ( `commit: parking command returned invalid result file : ${ err ?. message || err } ` )
225225 }
226226
227- return /** @type {ParkingResult } */ ( parkingResultSchema . parse ( parsed ) )
227+ const parkingResult = /** @type {ParkingResult } */ ( parkingResultSchema . parse ( parsed ) )
228+ await fs . rm ( resultPath , { force : true } )
229+
230+ if ( commandError && ! parkingResult . error ) {
231+ return {
232+ ...parkingResult ,
233+ error : commandError ,
234+ }
235+ }
236+
237+ return parkingResult
228238}
229239
230240/**
@@ -376,6 +386,15 @@ export async function runCommit({
376386 try {
377387 while ( true ) {
378388 const parkingResult = await runParkingBinary ( dir , target )
389+ if ( parkingResult . pieces . length > 0 ) {
390+ tracking . markParkedByPieceCids ( parkingResult . pieces )
391+ renderCommitProgress ( tracking . getCommitStats ( ) )
392+ }
393+
394+ if ( parkingResult . error ) {
395+ console . error ( `commit: parking batch error: ${ parkingResult . error } ` )
396+ }
397+
379398 if ( parkingResult . count === 0 ) {
380399 const recovered = await recoverParkedPieces ( {
381400 tracking,
@@ -385,11 +404,7 @@ export async function runCommit({
385404 if ( recovered === 0 ) return
386405
387406 renderCommitProgress ( tracking . getCommitStats ( ) )
388- continue
389407 }
390-
391- tracking . markParkedByPieceCids ( parkingResult . pieces )
392- renderCommitProgress ( tracking . getCommitStats ( ) )
393408 }
394409 } finally {
395410 parkingSettled = true
0 commit comments