fix: improve parallel pack downloads and suppress stale notifications
Some checks failed
Axolotl desktop CI / guardrails (push) Has been cancelled
Axolotl desktop CI / desktop (macos-latest) (push) Has been cancelled
Axolotl desktop CI / desktop (ubuntu-latest) (push) Has been cancelled
Axolotl desktop CI / desktop (windows-latest) (push) Has been cancelled
Axolotl desktop CI / website (push) Has been cancelled
Repository checks / typos (push) Has been cancelled
Repository checks / tombi (push) Has been cancelled
Rust checks / shear (push) Has been cancelled
Sync source to CNB / Sync Git ref (push) Has been cancelled
Sync LobeHub models / sync (push) Has been cancelled
Some checks failed
Axolotl desktop CI / guardrails (push) Has been cancelled
Axolotl desktop CI / desktop (macos-latest) (push) Has been cancelled
Axolotl desktop CI / desktop (ubuntu-latest) (push) Has been cancelled
Axolotl desktop CI / desktop (windows-latest) (push) Has been cancelled
Axolotl desktop CI / website (push) Has been cancelled
Repository checks / typos (push) Has been cancelled
Repository checks / tombi (push) Has been cancelled
Rust checks / shear (push) Has been cancelled
Sync source to CNB / Sync Git ref (push) Has been cancelled
Sync LobeHub models / sync (push) Has been cancelled
Download hosted pack files concurrently, recover file transfers from proxy and content-encoding failures, and prevent old installation failures from reappearing in notifications.
This commit is contained in:
@ -21,6 +21,7 @@ import {
|
||||
type InstallPhaseId,
|
||||
type InstallProgress,
|
||||
} from '@/helpers/install'
|
||||
import { createInstallJobNotificationFilter } from '@/helpers/install-job-notification-visibility'
|
||||
import { effectiveInstallProgress, hasDeterminateInstallProgress } from '@/helpers/install-progress'
|
||||
import { get_many as getInstances } from '@/helpers/instance'
|
||||
import type { DownloadManager } from '@/providers/download-manager'
|
||||
@ -258,15 +259,6 @@ const failureSummaryMessages = defineMessages({
|
||||
},
|
||||
})
|
||||
|
||||
const visibleJobStatuses = new Set<InstallJobStatus>([
|
||||
'queued',
|
||||
'running',
|
||||
'canceling',
|
||||
'waiting_for_user',
|
||||
'failed',
|
||||
'interrupted',
|
||||
])
|
||||
const retainedJobStatuses = new Set<InstallJobStatus>(['succeeded', 'canceled'])
|
||||
const activeJobStatuses = new Set<InstallJobStatus>([
|
||||
'queued',
|
||||
'running',
|
||||
@ -724,6 +716,8 @@ export async function useInstallJobNotifications(opts: {
|
||||
return buttons
|
||||
}
|
||||
|
||||
const filterVisibleJobs = createInstallJobNotificationFilter(opts.manager.jobs.value)
|
||||
|
||||
function setJobs(nextJobs: InstallJobSnapshot[]) {
|
||||
for (const job of nextJobs) {
|
||||
if (!jobOrder.has(job.job_id)) {
|
||||
@ -731,12 +725,7 @@ export async function useInstallJobNotifications(opts: {
|
||||
}
|
||||
}
|
||||
|
||||
const currentJobIds = new Set(jobs.value.map((job) => job.job_id))
|
||||
const visibleJobs = nextJobs.filter(
|
||||
(job) =>
|
||||
visibleJobStatuses.has(job.status) ||
|
||||
(retainedJobStatuses.has(job.status) && currentJobIds.has(job.job_id)),
|
||||
)
|
||||
const visibleJobs = filterVisibleJobs(nextJobs)
|
||||
syncProgressSnapshots(visibleJobs)
|
||||
|
||||
jobs.value = visibleJobs.sort(
|
||||
|
||||
@ -0,0 +1,35 @@
|
||||
import assert from 'node:assert/strict'
|
||||
import test from 'node:test'
|
||||
|
||||
import type { InstallJobSnapshot, InstallJobStatus } from './install.ts'
|
||||
import { createInstallJobNotificationFilter } from './install-job-notification-visibility.ts'
|
||||
|
||||
function job(jobId: string, status: InstallJobStatus): InstallJobSnapshot {
|
||||
return { job_id: jobId, status } as InstallJobSnapshot
|
||||
}
|
||||
|
||||
test('does not resurrect failures that finished before the notification surface started', () => {
|
||||
const oldFailure = job('old-failure', 'failed')
|
||||
const filter = createInstallJobNotificationFilter([oldFailure, job('old-success', 'succeeded')])
|
||||
|
||||
assert.deepEqual(filter([oldFailure, job('old-success', 'succeeded')]), [])
|
||||
assert.deepEqual(filter([oldFailure, job('current', 'running')]).map((item) => item.job_id), [
|
||||
'current',
|
||||
])
|
||||
})
|
||||
|
||||
test('keeps an observed task visible when it finishes', () => {
|
||||
const filter = createInstallJobNotificationFilter([job('old-failure', 'failed')])
|
||||
|
||||
assert.deepEqual(filter([job('current', 'running')]).map((item) => item.job_id), ['current'])
|
||||
assert.deepEqual(filter([job('current', 'failed')]).map((item) => item.job_id), ['current'])
|
||||
assert.deepEqual(filter([job('current', 'succeeded')]).map((item) => item.job_id), ['current'])
|
||||
})
|
||||
|
||||
test('shows a newly received failure even if its active phase completed too quickly to observe', () => {
|
||||
const filter = createInstallJobNotificationFilter([job('old-failure', 'failed')])
|
||||
|
||||
assert.deepEqual(filter([job('new-failure', 'failed')]).map((item) => item.job_id), [
|
||||
'new-failure',
|
||||
])
|
||||
})
|
||||
@ -0,0 +1,32 @@
|
||||
import type { InstallJobSnapshot, InstallJobStatus } from './install.ts'
|
||||
|
||||
const activeStatuses = new Set<InstallJobStatus>([
|
||||
'queued',
|
||||
'running',
|
||||
'canceling',
|
||||
'waiting_for_user',
|
||||
])
|
||||
const failureStatuses = new Set<InstallJobStatus>(['failed', 'interrupted'])
|
||||
|
||||
/**
|
||||
* Keeps the popup scoped to work the user could actually have observed.
|
||||
* Finished jobs already present when the action bar starts belong to download
|
||||
* history; they must not be resurrected by an unrelated loading event.
|
||||
*/
|
||||
export function createInstallJobNotificationFilter(initialJobs: InstallJobSnapshot[]) {
|
||||
const missedFinishedJobIds = new Set(
|
||||
initialJobs.filter((job) => !activeStatuses.has(job.status)).map((job) => job.job_id),
|
||||
)
|
||||
let visibleJobIds = new Set<string>()
|
||||
|
||||
return (nextJobs: InstallJobSnapshot[]) => {
|
||||
const visibleJobs = nextJobs.filter((job) => {
|
||||
if (activeStatuses.has(job.status)) return true
|
||||
if (visibleJobIds.has(job.job_id)) return true
|
||||
return failureStatuses.has(job.status) && !missedFinishedJobIds.has(job.job_id)
|
||||
})
|
||||
|
||||
visibleJobIds = new Set(visibleJobs.map((job) => job.job_id))
|
||||
return visibleJobs
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user