checking on transfers, #141
This commit is contained in:
+51
-7
@@ -117,6 +117,12 @@ export async function startCopy({
|
|||||||
remotes?: Record<string, Record<string, FlagValue>>
|
remotes?: Record<string, Record<string, FlagValue>>
|
||||||
}
|
}
|
||||||
}) {
|
}) {
|
||||||
|
console.log('[startCopy] starting', {
|
||||||
|
sources,
|
||||||
|
destination,
|
||||||
|
optionKeys: Object.keys(options),
|
||||||
|
})
|
||||||
|
|
||||||
for (const source of sources) {
|
for (const source of sources) {
|
||||||
const sourceExists = await hasStat(source)
|
const sourceExists = await hasStat(source)
|
||||||
if (!sourceExists) {
|
if (!sourceExists) {
|
||||||
@@ -228,6 +234,7 @@ export async function startCopy({
|
|||||||
pendingJobs.push(jobParams)
|
pendingJobs.push(jobParams)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
console.log('[startCopy] submitting batch', { jobCount: pendingJobs.length })
|
||||||
return startBatch(pendingJobs)
|
return startBatch(pendingJobs)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -245,6 +252,12 @@ export async function startMove({
|
|||||||
remotes?: Record<string, Record<string, FlagValue>>
|
remotes?: Record<string, Record<string, FlagValue>>
|
||||||
}
|
}
|
||||||
}) {
|
}) {
|
||||||
|
console.log('[startMove] starting', {
|
||||||
|
sources,
|
||||||
|
destination,
|
||||||
|
optionKeys: Object.keys(options),
|
||||||
|
})
|
||||||
|
|
||||||
for (const source of sources) {
|
for (const source of sources) {
|
||||||
const sourceExists = await hasStat(source)
|
const sourceExists = await hasStat(source)
|
||||||
if (!sourceExists) {
|
if (!sourceExists) {
|
||||||
@@ -345,6 +358,7 @@ export async function startMove({
|
|||||||
pendingJobs.push(jobParams)
|
pendingJobs.push(jobParams)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
console.log('[startMove] submitting batch', { jobCount: pendingJobs.length })
|
||||||
return startBatch(pendingJobs)
|
return startBatch(pendingJobs)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -365,6 +379,7 @@ async function fetchJob(jobId: number, transferred: Awaited<ReturnType<typeof fe
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
console.log('[fetchJob] job stats', jobId, JSON.stringify(job, null, 2))
|
||||||
|
|
||||||
const jobStatus = await rclone('/job/status', {
|
const jobStatus = await rclone('/job/status', {
|
||||||
params: {
|
params: {
|
||||||
@@ -373,6 +388,7 @@ async function fetchJob(jobId: number, transferred: Awaited<ReturnType<typeof fe
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
console.log('[fetchJob] job status', jobId, JSON.stringify(jobStatus, null, 2))
|
||||||
|
|
||||||
let hasError = !!jobStatus?.error
|
let hasError = !!jobStatus?.error
|
||||||
|
|
||||||
@@ -438,13 +454,17 @@ async function fetchJob(jobId: number, transferred: Awaited<ReturnType<typeof fe
|
|||||||
}
|
}
|
||||||
|
|
||||||
export async function listTransfers() {
|
export async function listTransfers() {
|
||||||
console.log('[listTransfers]')
|
console.log('[listTransfers] starting')
|
||||||
|
|
||||||
const allStats = await rclone('/core/stats')
|
const allStats = await rclone('/core/stats')
|
||||||
|
console.log('[listTransfers] allStats', JSON.stringify(allStats, null, 2))
|
||||||
|
|
||||||
const transferring = allStats?.transferring
|
const transferring = allStats?.transferring || []
|
||||||
|
|
||||||
|
console.log('[listTransfers] transferring count:', transferring.length)
|
||||||
|
|
||||||
const transferred = await fetchTransferred()
|
const transferred = await fetchTransferred()
|
||||||
|
console.log('[listTransfers] transferred count:', transferred?.length || 0)
|
||||||
|
|
||||||
const jobs = {
|
const jobs = {
|
||||||
active: [] as JobItem[],
|
active: [] as JobItem[],
|
||||||
@@ -479,6 +499,7 @@ export async function listTransfers() {
|
|||||||
.filter((id) => !activeJobIds.has(id))
|
.filter((id) => !activeJobIds.has(id))
|
||||||
.sort((a, b) => a - b)
|
.sort((a, b) => a - b)
|
||||||
)
|
)
|
||||||
|
console.log('[listTransfers] inactive job IDs:', Array.from(inactiveJobIds))
|
||||||
|
|
||||||
for (const jobId of inactiveJobIds) {
|
for (const jobId of inactiveJobIds) {
|
||||||
const job = await fetchJob(jobId, transferred)
|
const job = await fetchJob(jobId, transferred)
|
||||||
@@ -491,6 +512,13 @@ export async function listTransfers() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
console.log(
|
||||||
|
'[listTransfers] final result - active:',
|
||||||
|
jobs.active.length,
|
||||||
|
'inactive:',
|
||||||
|
jobs.inactive.length
|
||||||
|
)
|
||||||
|
|
||||||
return jobs
|
return jobs
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1090,7 +1118,11 @@ export async function startServe({
|
|||||||
}
|
}
|
||||||
|
|
||||||
export async function startBatch(inputs: ({ _path: string } & Record<string, any>)[]) {
|
export async function startBatch(inputs: ({ _path: string } & Record<string, any>)[]) {
|
||||||
console.log('[startBatch] inputs', inputs)
|
console.log('[startBatch] starting batch operation', {
|
||||||
|
inputCount: inputs.length,
|
||||||
|
paths: inputs.map((i) => i._path),
|
||||||
|
})
|
||||||
|
console.log('[startBatch] inputs', JSON.stringify(inputs, null, 2))
|
||||||
|
|
||||||
const r = await pRetry(
|
const r = await pRetry(
|
||||||
async () =>
|
async () =>
|
||||||
@@ -1105,6 +1137,8 @@ export async function startBatch(inputs: ({ _path: string } & Record<string, any
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
console.log('[startBatch] job created', { jobid: r.jobid })
|
||||||
|
|
||||||
await new Promise((resolve) => setTimeout(resolve, 1000))
|
await new Promise((resolve) => setTimeout(resolve, 1000))
|
||||||
|
|
||||||
const jobStatus = await pRetry(
|
const jobStatus = await pRetry(
|
||||||
@@ -1121,10 +1155,16 @@ export async function startBatch(inputs: ({ _path: string } & Record<string, any
|
|||||||
}
|
}
|
||||||
).catch(null)
|
).catch(null)
|
||||||
|
|
||||||
console.log('jobStatus', JSON.stringify(jobStatus, null, 2))
|
console.log('[startBatch] jobStatus', {
|
||||||
|
jobid: r.jobid,
|
||||||
|
finished: jobStatus?.finished,
|
||||||
|
success: jobStatus?.success,
|
||||||
|
error: jobStatus?.error,
|
||||||
|
})
|
||||||
|
console.log('[startBatch] jobStatus full', JSON.stringify(jobStatus, null, 2))
|
||||||
|
|
||||||
if (!jobStatus) {
|
if (!jobStatus) {
|
||||||
console.error('Failed to start job:', r.jobid)
|
console.error('[startBatch] ERROR: job status is null', { jobid: r.jobid })
|
||||||
throw new Error('Failed to start operation')
|
throw new Error('Failed to start operation')
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1145,16 +1185,20 @@ export async function startBatch(inputs: ({ _path: string } & Record<string, any
|
|||||||
})
|
})
|
||||||
.join('\n')
|
.join('\n')
|
||||||
|
|
||||||
console.error('All batch operations failed:', errorMessages)
|
console.error('[startBatch] ERROR: all batch operations failed', {
|
||||||
|
jobid: r.jobid,
|
||||||
|
errorMessages,
|
||||||
|
})
|
||||||
throw new Error(errorMessages)
|
throw new Error(errorMessages)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (jobStatus.error) {
|
if (jobStatus.error) {
|
||||||
console.error('Failed to start job:', r.jobid, jobStatus.error)
|
console.error('[startBatch] ERROR: job failed', { jobid: r.jobid, error: jobStatus.error })
|
||||||
throw new Error(jobStatus.error)
|
throw new Error(jobStatus.error)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
console.log('[startBatch] SUCCESS', { jobid: r.jobid })
|
||||||
return r.jobid
|
return r.jobid
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+12
-10
@@ -63,24 +63,27 @@ export default async function rclone<
|
|||||||
path: Path,
|
path: Path,
|
||||||
...init: InitParam<Init>
|
...init: InitParam<Init>
|
||||||
): Promise<OpenApiMethodResponse<RCDClient, 'post', Path, Init>> {
|
): Promise<OpenApiMethodResponse<RCDClient, 'post', Path, Init>> {
|
||||||
console.log('[rclone] STARTING', path)
|
console.log('[rclone] REQUEST', path, {
|
||||||
|
params: init[0]?.params,
|
||||||
|
body: init[0]?.body,
|
||||||
|
})
|
||||||
|
|
||||||
const client = await pRetry(() => getClient(), {
|
const client = await pRetry(() => getClient(), {
|
||||||
'maxTimeout': 500,
|
'maxTimeout': 500,
|
||||||
}) //! for some reason this still fails sometimes
|
}) //! for some reason this still fails sometimes
|
||||||
|
|
||||||
if (!client) {
|
if (!client) {
|
||||||
|
console.error('[rclone] ERROR: Failed to get client after retries', path)
|
||||||
throw new Error('Failed to get client after retries')
|
throw new Error('Failed to get client after retries')
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log('[rclone] init', init)
|
|
||||||
const result = await client.POST(
|
const result = await client.POST(
|
||||||
path,
|
path,
|
||||||
...(init as InitParam<OpenApiMaybeOptionalInit<Paths[Path], 'post'>>)
|
...(init as InitParam<OpenApiMaybeOptionalInit<Paths[Path], 'post'>>)
|
||||||
)
|
)
|
||||||
|
|
||||||
if (result?.error) {
|
if (result?.error) {
|
||||||
console.log('[rclone] result?.error', result.error)
|
console.error('[rclone] ERROR', path, { error: result.error })
|
||||||
const message =
|
const message =
|
||||||
typeof result.error === 'string' ? result.error : JSON.stringify(result.error)
|
typeof result.error === 'string' ? result.error : JSON.stringify(result.error)
|
||||||
|
|
||||||
@@ -89,22 +92,21 @@ export default async function rclone<
|
|||||||
|
|
||||||
const data = result.data as { error?: unknown } | undefined
|
const data = result.data as { error?: unknown } | undefined
|
||||||
if (data?.error) {
|
if (data?.error) {
|
||||||
console.log('[rclone] data?.error', data.error)
|
console.error('[rclone] DATA ERROR', path, { error: data.error })
|
||||||
const message = typeof data.error === 'string' ? data.error : JSON.stringify(data.error)
|
const message = typeof data.error === 'string' ? data.error : JSON.stringify(data.error)
|
||||||
|
|
||||||
throw new Error(message)
|
throw new Error(message)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!result.response.ok) {
|
if (!result.response.ok) {
|
||||||
console.log(
|
console.error('[rclone] HTTP ERROR', path, {
|
||||||
'[rclone] !result.response.ok',
|
status: result.response.status,
|
||||||
result.response.status,
|
statusText: result.response.statusText,
|
||||||
result.response.statusText
|
})
|
||||||
)
|
|
||||||
throw new Error(`${result.response.status} ${result.response.statusText}`)
|
throw new Error(`${result.response.status} ${result.response.statusText}`)
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log('[rclone] ENDING', path)
|
console.log('[rclone] RESPONSE', path, { hasData: !!result.data })
|
||||||
|
|
||||||
return result.data as OpenApiMethodResponse<typeof client, 'post', Path, Init>
|
return result.data as OpenApiMethodResponse<typeof client, 'post', Path, Init>
|
||||||
}
|
}
|
||||||
|
|||||||
+10
-1
@@ -59,7 +59,16 @@ export default function Transfers() {
|
|||||||
[transfersQuery.data]
|
[transfersQuery.data]
|
||||||
)
|
)
|
||||||
|
|
||||||
console.log('transfers', JSON.stringify(transfers, null, 2))
|
console.log('[Transfers] query state', {
|
||||||
|
isLoading: transfersQuery.isLoading,
|
||||||
|
isRefetching: transfersQuery.isRefetching,
|
||||||
|
isError: transfersQuery.isError,
|
||||||
|
error: transfersQuery.error,
|
||||||
|
activeCount: transfers.active.length,
|
||||||
|
inactiveCount: transfers.inactive.length,
|
||||||
|
checkingJobs: transfers.active.filter((j) => j.isChecking).length,
|
||||||
|
})
|
||||||
|
console.log('[Transfers] data', JSON.stringify(transfers, null, 2))
|
||||||
|
|
||||||
if (transfersQuery.isLoading) {
|
if (transfersQuery.isLoading) {
|
||||||
return (
|
return (
|
||||||
|
|||||||
Reference in New Issue
Block a user