@filoz/repair-cli 0.1.2 → 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/package.json +1 -1
- package/dist/src/cli.js +2 -0
- package/dist/src/cli.js.map +1 -1
- package/dist/src/commands/datasets.d.ts +1 -0
- package/dist/src/commands/datasets.d.ts.map +1 -1
- package/dist/src/commands/datasets.js +14 -3
- package/dist/src/commands/datasets.js.map +1 -1
- package/dist/src/commands/providers.d.ts +1 -0
- package/dist/src/commands/providers.d.ts.map +1 -1
- package/dist/src/commands/providers.js.map +1 -1
- package/dist/src/commands/repair.d.ts +1 -0
- package/dist/src/commands/repair.d.ts.map +1 -1
- package/dist/src/commands/repair.js +7 -8
- package/dist/src/commands/repair.js.map +1 -1
- package/dist/src/commands/replicate.d.ts +24 -0
- package/dist/src/commands/replicate.d.ts.map +1 -0
- package/dist/src/commands/replicate.js +171 -0
- package/dist/src/commands/replicate.js.map +1 -0
- package/dist/src/commands/setup.d.ts +0 -1
- package/dist/src/commands/setup.d.ts.map +1 -1
- package/dist/src/commands/setup.js +17 -4
- package/dist/src/commands/setup.js.map +1 -1
- package/dist/src/commands/wallet.d.ts +1 -0
- package/dist/src/commands/wallet.d.ts.map +1 -1
- package/dist/src/db/dedupe-cids.d.ts +22 -0
- package/dist/src/db/dedupe-cids.d.ts.map +1 -0
- package/dist/src/db/dedupe-cids.js +28 -0
- package/dist/src/db/dedupe-cids.js.map +1 -0
- package/dist/src/db/find-providers-by-cid.d.ts +9 -0
- package/dist/src/db/find-providers-by-cid.d.ts.map +1 -0
- package/dist/src/db/{get-providers-by-cid.js → find-providers-by-cid.js} +4 -6
- package/dist/src/db/find-providers-by-cid.js.map +1 -0
- package/dist/src/db/find-repair-dataset.d.ts +10 -0
- package/dist/src/db/find-repair-dataset.d.ts.map +1 -0
- package/dist/src/db/{get-repair-dataset.js → find-repair-dataset.js} +3 -4
- package/dist/src/db/find-repair-dataset.js.map +1 -0
- package/dist/src/db/get-pieces.d.ts +16 -0
- package/dist/src/db/get-pieces.d.ts.map +1 -1
- package/dist/src/db/get-pieces.js +44 -3
- package/dist/src/db/get-pieces.js.map +1 -1
- package/dist/src/db/repair-create.d.ts.map +1 -1
- package/dist/src/db/repair-create.js +1 -0
- package/dist/src/db/repair-create.js.map +1 -1
- package/dist/src/db/repair-delete.d.ts.map +1 -1
- package/dist/src/db/repair-delete.js +0 -5
- package/dist/src/db/repair-delete.js.map +1 -1
- package/dist/src/db/replicate-create.d.ts +7 -0
- package/dist/src/db/replicate-create.d.ts.map +1 -0
- package/dist/src/db/replicate-create.js +78 -0
- package/dist/src/db/replicate-create.js.map +1 -0
- package/dist/src/db/upsert-operations.js +1 -1
- package/dist/src/db/upsert-operations.js.map +1 -1
- package/dist/src/local-schema.d.ts +19 -0
- package/dist/src/local-schema.d.ts.map +1 -1
- package/dist/src/local-schema.js +1 -0
- package/dist/src/local-schema.js.map +1 -1
- package/dist/src/middleware.d.ts +2 -0
- package/dist/src/middleware.d.ts.map +1 -1
- package/dist/src/middleware.js +4 -2
- package/dist/src/middleware.js.map +1 -1
- package/dist/src/pipeline/add-pieces.d.ts +12 -0
- package/dist/src/pipeline/add-pieces.d.ts.map +1 -0
- package/dist/src/pipeline/add-pieces.js +143 -0
- package/dist/src/pipeline/add-pieces.js.map +1 -0
- package/dist/src/pipeline/create-datasets.d.ts +3 -1
- package/dist/src/pipeline/create-datasets.d.ts.map +1 -1
- package/dist/src/pipeline/create-datasets.js +57 -5
- package/dist/src/pipeline/create-datasets.js.map +1 -1
- package/dist/src/utils.d.ts +32 -2
- package/dist/src/utils.d.ts.map +1 -1
- package/dist/src/utils.js +40 -7
- package/dist/src/utils.js.map +1 -1
- package/package.json +1 -1
- package/readme.md +110 -7
- package/src/cli.ts +2 -0
- package/src/commands/datasets.ts +15 -4
- package/src/commands/providers.ts +0 -1
- package/src/commands/repair.ts +12 -8
- package/src/commands/replicate.ts +183 -0
- package/src/commands/setup.ts +18 -4
- package/src/db/dedupe-cids.ts +49 -0
- package/src/db/{get-providers-by-cid.ts → find-providers-by-cid.ts} +5 -10
- package/src/db/{get-repair-dataset.ts → find-repair-dataset.ts} +6 -5
- package/src/db/get-pieces.ts +105 -3
- package/src/db/get-target-dataset.ts +1 -1
- package/src/db/repair-create.ts +1 -0
- package/src/db/repair-delete.ts +0 -5
- package/src/db/replicate-create.ts +106 -0
- package/src/db/upsert-operations.ts +1 -1
- package/src/local-schema.ts +1 -0
- package/src/middleware.ts +4 -2
- package/src/pipeline/add-pieces.ts +215 -0
- package/src/pipeline/create-datasets.ts +71 -5
- package/src/utils.ts +49 -10
- package/dist/src/db/get-providers-by-cid.d.ts +0 -10
- package/dist/src/db/get-providers-by-cid.d.ts.map +0 -1
- package/dist/src/db/get-providers-by-cid.js.map +0 -1
- package/dist/src/db/get-repair-dataset.d.ts +0 -9
- package/dist/src/db/get-repair-dataset.d.ts.map +0 -1
- package/dist/src/db/get-repair-dataset.js.map +0 -1
- package/dist/src/db/sync-pieces-onchain.d.ts +0 -10
- package/dist/src/db/sync-pieces-onchain.d.ts.map +0 -1
- package/dist/src/db/sync-pieces-onchain.js +0 -35
- package/dist/src/db/sync-pieces-onchain.js.map +0 -1
- package/dist/src/pipeline/pull.d.ts +0 -30
- package/dist/src/pipeline/pull.d.ts.map +0 -1
- package/dist/src/pipeline/pull.js +0 -169
- package/dist/src/pipeline/pull.js.map +0 -1
- package/src/db/sync-pieces-onchain.ts +0 -53
- package/src/pipeline/pull.ts +0 -255
package/src/pipeline/pull.ts
DELETED
|
@@ -1,255 +0,0 @@
|
|
|
1
|
-
import { taskLog } from '@clack/prompts'
|
|
2
|
-
import * as Piece from '@filoz/synapse-core/piece'
|
|
3
|
-
import { createPieceUrlPDP } from '@filoz/synapse-core/piece'
|
|
4
|
-
import * as SP from '@filoz/synapse-core/sp'
|
|
5
|
-
import { and, asc, eq, gt, inArray } from 'drizzle-orm'
|
|
6
|
-
import PQueue from 'p-queue'
|
|
7
|
-
import { getTargetDataset } from '../db/get-target-dataset.ts'
|
|
8
|
-
import { syncPiecesOnchain } from '../db/sync-pieces-onchain.ts'
|
|
9
|
-
import { updateOperation } from '../db/update-operation.ts'
|
|
10
|
-
import { upsertOperations } from '../db/upsert-operations.ts'
|
|
11
|
-
import type { OperationSelect, RepairSelect } from '../local-schema.ts'
|
|
12
|
-
import type { IndexerDatabase, LocalDatabase, WalletClient } from '../types.ts'
|
|
13
|
-
import { hashLink } from '../utils.ts'
|
|
14
|
-
|
|
15
|
-
/** Pending `add_piece` operations batched for a single pull job. */
|
|
16
|
-
export type PullPiecesBatch = {
|
|
17
|
-
operations: OperationSelect[]
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
export type RunPullPiecesPhaseOptions = {
|
|
21
|
-
localDb: LocalDatabase
|
|
22
|
-
indexerDb: IndexerDatabase
|
|
23
|
-
repair: RepairSelect
|
|
24
|
-
concurrency: number
|
|
25
|
-
batchSize: number
|
|
26
|
-
client: WalletClient
|
|
27
|
-
reset: boolean
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
/** Mock pull worker: logs each batch and its piece CIDs. */
|
|
31
|
-
export function createPullPiecesWorker({
|
|
32
|
-
localDb,
|
|
33
|
-
indexerDb,
|
|
34
|
-
repair,
|
|
35
|
-
client,
|
|
36
|
-
state,
|
|
37
|
-
log,
|
|
38
|
-
}: {
|
|
39
|
-
localDb: LocalDatabase
|
|
40
|
-
indexerDb: IndexerDatabase
|
|
41
|
-
repair: RepairSelect
|
|
42
|
-
client: WalletClient
|
|
43
|
-
state: {
|
|
44
|
-
totalBatches: number
|
|
45
|
-
totalOperations: number
|
|
46
|
-
completedOperations: number
|
|
47
|
-
failedOperations: number
|
|
48
|
-
}
|
|
49
|
-
log: ReturnType<typeof taskLog>
|
|
50
|
-
}) {
|
|
51
|
-
return async (batch: PullPiecesBatch, batchNumber: number) => {
|
|
52
|
-
let completedCids = 0
|
|
53
|
-
let failedCids = 0
|
|
54
|
-
const cidToOperation = new Map<string, OperationSelect>()
|
|
55
|
-
|
|
56
|
-
const spin = log.group(`Batch ${batchNumber}/${state.totalBatches}`)
|
|
57
|
-
spin.message(`Pull 0 completed, 0 failed`)
|
|
58
|
-
|
|
59
|
-
try {
|
|
60
|
-
const dataset = await getTargetDataset({ localDb, repairId: repair.id, client })
|
|
61
|
-
|
|
62
|
-
for (const operation of batch.operations) {
|
|
63
|
-
cidToOperation.set(operation.cid, operation)
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
// sync pieces onchain to avoid duplicates
|
|
67
|
-
const completedOperations1 = await syncPiecesOnchain({
|
|
68
|
-
indexerDb,
|
|
69
|
-
localDb,
|
|
70
|
-
dataSetId: dataset.dataSetId,
|
|
71
|
-
cidToOperation,
|
|
72
|
-
})
|
|
73
|
-
state.completedOperations += completedOperations1
|
|
74
|
-
completedCids += completedOperations1
|
|
75
|
-
|
|
76
|
-
// create pull pieces
|
|
77
|
-
const pullPieces: SP.PullPieceInput[] = []
|
|
78
|
-
for (const [cid, operation] of cidToOperation) {
|
|
79
|
-
const pieceCid = Piece.from(cid)
|
|
80
|
-
const sourceUrl = createPieceUrlPDP({
|
|
81
|
-
cid,
|
|
82
|
-
serviceURL: operation.alternateProvider,
|
|
83
|
-
})
|
|
84
|
-
pullPieces.push({ pieceCid, sourceUrl })
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
if (pullPieces.length > 0) {
|
|
88
|
-
// wait for pull pieces
|
|
89
|
-
const pullResult = await SP.waitForPullPieces(client, {
|
|
90
|
-
serviceURL: repair.targetProviderUrl,
|
|
91
|
-
dataSetId: dataset.dataSetId,
|
|
92
|
-
clientDataSetId: dataset.clientDataSetId,
|
|
93
|
-
pieces: pullPieces,
|
|
94
|
-
timeout: 1000 * 60 * 30,
|
|
95
|
-
onStatus: (_status) => {
|
|
96
|
-
const completed = _status.pieces.filter((piece) => piece.status === 'complete').length
|
|
97
|
-
const failed = _status.pieces.filter((piece) => piece.status === 'failed').length
|
|
98
|
-
spin.message(`Pull ${completed} completed, ${failed} failed`)
|
|
99
|
-
},
|
|
100
|
-
})
|
|
101
|
-
|
|
102
|
-
for (const { pieceCid, status } of pullResult.pieces) {
|
|
103
|
-
const cid = pieceCid.toString()
|
|
104
|
-
const operation = cidToOperation.get(cid)
|
|
105
|
-
if (!operation) {
|
|
106
|
-
console.log(`operation not found for cid ${cid}`)
|
|
107
|
-
continue
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
if (status !== 'complete') {
|
|
111
|
-
state.failedOperations++
|
|
112
|
-
failedCids++
|
|
113
|
-
cidToOperation.delete(cid)
|
|
114
|
-
await updateOperation({
|
|
115
|
-
localDb,
|
|
116
|
-
operationId: operation.id,
|
|
117
|
-
status: 'failed',
|
|
118
|
-
error: `pull failed with status ${status}`,
|
|
119
|
-
})
|
|
120
|
-
}
|
|
121
|
-
}
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
// sync against indexer to avoid duplicates
|
|
125
|
-
const completedOperations2 = await syncPiecesOnchain({
|
|
126
|
-
indexerDb,
|
|
127
|
-
localDb,
|
|
128
|
-
dataSetId: dataset.dataSetId,
|
|
129
|
-
cidToOperation,
|
|
130
|
-
})
|
|
131
|
-
state.completedOperations += completedOperations2
|
|
132
|
-
completedCids += completedOperations2
|
|
133
|
-
|
|
134
|
-
const commitPieces: SP.addPieces.PieceType[] = []
|
|
135
|
-
for (const [cid] of cidToOperation) {
|
|
136
|
-
commitPieces.push({
|
|
137
|
-
pieceCid: Piece.from(cid),
|
|
138
|
-
})
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
if (commitPieces.length > 0) {
|
|
142
|
-
const addPiecesResult = await SP.addPieces(client, {
|
|
143
|
-
serviceURL: repair.targetProviderUrl,
|
|
144
|
-
dataSetId: dataset.dataSetId,
|
|
145
|
-
clientDataSetId: dataset.clientDataSetId,
|
|
146
|
-
pieces: commitPieces,
|
|
147
|
-
})
|
|
148
|
-
|
|
149
|
-
spin.message(`Waiting for add pieces ${hashLink(addPiecesResult.txHash, client.chain)}...`)
|
|
150
|
-
const addPiecesResult2 = await SP.waitForAddPieces(addPiecesResult)
|
|
151
|
-
state.completedOperations += cidToOperation.size
|
|
152
|
-
completedCids += cidToOperation.size
|
|
153
|
-
await upsertOperations({
|
|
154
|
-
localDb,
|
|
155
|
-
operations: Array.from(cidToOperation.values()).map((operation) => ({
|
|
156
|
-
...operation,
|
|
157
|
-
status: 'completed',
|
|
158
|
-
error: null,
|
|
159
|
-
result: { dataSetId: addPiecesResult2.dataSetId, txHash: addPiecesResult2.txHash },
|
|
160
|
-
})),
|
|
161
|
-
})
|
|
162
|
-
}
|
|
163
|
-
spin.success(`Batch ${batchNumber}/${state.totalBatches} ${completedCids} added, ${failedCids} failed`)
|
|
164
|
-
} catch (error) {
|
|
165
|
-
state.failedOperations += cidToOperation.size
|
|
166
|
-
const message = error instanceof Error ? error.message : 'Unknown error'
|
|
167
|
-
spin.error(`Batch ${batchNumber}/${state.totalBatches} - ${message.replace(/\n/g, ' ')}`)
|
|
168
|
-
await upsertOperations({
|
|
169
|
-
localDb,
|
|
170
|
-
operations: Array.from(cidToOperation.values()).map((operation) => ({
|
|
171
|
-
...operation,
|
|
172
|
-
status: 'failed',
|
|
173
|
-
error: message,
|
|
174
|
-
})),
|
|
175
|
-
})
|
|
176
|
-
}
|
|
177
|
-
}
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
/**
|
|
181
|
-
* Pull pending `add_piece` operations without loading the whole repair into memory.
|
|
182
|
-
*
|
|
183
|
-
* Pending piece operations are fetched lazily and queued with bounded backpressure. Failed piece
|
|
184
|
-
* operations are intentionally skipped unless `reset` is set.
|
|
185
|
-
*/
|
|
186
|
-
export async function runPullPiecesPhase({
|
|
187
|
-
localDb,
|
|
188
|
-
indexerDb,
|
|
189
|
-
repair,
|
|
190
|
-
concurrency,
|
|
191
|
-
batchSize,
|
|
192
|
-
client,
|
|
193
|
-
reset,
|
|
194
|
-
}: RunPullPiecesPhaseOptions): Promise<void> {
|
|
195
|
-
const localSchema = localDb._.fullSchema
|
|
196
|
-
const pullConcurrency = Math.max(1, concurrency)
|
|
197
|
-
const pullBatchSize = Math.max(1, batchSize)
|
|
198
|
-
let pullCursor = 0
|
|
199
|
-
|
|
200
|
-
const totalOperations = await localDb.$count(
|
|
201
|
-
localSchema.operations,
|
|
202
|
-
and(
|
|
203
|
-
eq(localSchema.operations.repairId, repair.id),
|
|
204
|
-
eq(localSchema.operations.type, 'add_piece'),
|
|
205
|
-
inArray(localSchema.operations.status, reset ? ['pending', 'failed'] : ['pending'])
|
|
206
|
-
)
|
|
207
|
-
)
|
|
208
|
-
let batchNumber = 0
|
|
209
|
-
const state = {
|
|
210
|
-
totalBatches: Math.ceil(totalOperations / pullBatchSize),
|
|
211
|
-
totalOperations,
|
|
212
|
-
completedOperations: 0,
|
|
213
|
-
failedOperations: 0,
|
|
214
|
-
}
|
|
215
|
-
|
|
216
|
-
const log = taskLog({
|
|
217
|
-
title: 'Pulling pieces',
|
|
218
|
-
limit: 1,
|
|
219
|
-
})
|
|
220
|
-
|
|
221
|
-
async function getNextPullBatch(): Promise<PullPiecesBatch | null> {
|
|
222
|
-
const operations = await localDb.query.operations.findMany({
|
|
223
|
-
where: and(
|
|
224
|
-
eq(localSchema.operations.repairId, repair.id),
|
|
225
|
-
eq(localSchema.operations.type, 'add_piece'),
|
|
226
|
-
inArray(localSchema.operations.status, reset ? ['pending', 'failed'] : ['pending']),
|
|
227
|
-
gt(localSchema.operations.id, pullCursor)
|
|
228
|
-
),
|
|
229
|
-
orderBy: [asc(localSchema.operations.id)],
|
|
230
|
-
limit: pullBatchSize,
|
|
231
|
-
})
|
|
232
|
-
if (operations.length === 0) {
|
|
233
|
-
return null
|
|
234
|
-
}
|
|
235
|
-
|
|
236
|
-
pullCursor = operations.at(-1)?.id ?? pullCursor
|
|
237
|
-
return { operations }
|
|
238
|
-
}
|
|
239
|
-
|
|
240
|
-
const pullPiecesWorker = createPullPiecesWorker({ localDb, indexerDb, repair, client, state, log })
|
|
241
|
-
const pullPiecesQueue = new PQueue({ concurrency: pullConcurrency })
|
|
242
|
-
|
|
243
|
-
while (true) {
|
|
244
|
-
await pullPiecesQueue.onSizeLessThan(pullConcurrency)
|
|
245
|
-
const batch = await getNextPullBatch()
|
|
246
|
-
if (!batch) break
|
|
247
|
-
batchNumber++
|
|
248
|
-
const currentBatchNumber = batchNumber
|
|
249
|
-
pullPiecesQueue.add(() => pullPiecesWorker(batch, currentBatchNumber)).catch(console.error)
|
|
250
|
-
}
|
|
251
|
-
|
|
252
|
-
await pullPiecesQueue.onIdle()
|
|
253
|
-
|
|
254
|
-
log.success(`Pulled ${state.completedOperations} pieces, ${state.failedOperations} failed`)
|
|
255
|
-
}
|