[Manager] Optimize conflict detection with bulk API and version support (#4538)

This commit is contained in:
Jin Yi
2025-07-27 08:06:09 +09:00
parent 5f9ed0289c
commit aff42a9e47
3 changed files with 112 additions and 34 deletions

View File

@@ -36,11 +36,29 @@ export const useInstalledPacks = (options: UseNodePacksOptions = {}) => {
cleanup()
})
// Create a computed property that provides installed pack info with versions
const installedPacksWithVersions = computed(() => {
const result: Array<{ id: string; version: string }> = []
for (const pack of Object.values(comfyManagerStore.installedPacks)) {
const id = pack.cnr_id || pack.aux_id
if (id) {
result.push({
id,
version: pack.ver
})
}
}
return result
})
return {
error,
isLoading,
isReady,
installedPacks: nodePacks,
installedPacksWithVersions,
startFetchInstalled,
filterInstalledPack
}

View File

@@ -40,6 +40,7 @@ export function useConflictDetection() {
const {
startFetchInstalled,
installedPacks,
installedPacksWithVersions,
isReady: installedPacksReady
} = useInstalledPacks()
@@ -203,58 +204,67 @@ export function useConflictDetection() {
return []
}
// Step 2: Get Registry service for individual API calls
// Step 2: Get Registry service for bulk API calls
const registryService = useComfyRegistryService()
// Step 3: Setup abort controller for request cancellation
abortController.value = new AbortController()
// Step 4: Fetch version-specific data in chunks to avoid overwhelming the Registry API
// - Each chunk processes up to 30 packages concurrently
// - Results are stored in versionDataMap for later use
// - Use installedPacks from useInstalledPacks composable
const chunkSize = 30
// Step 4: Use bulk API to fetch all version data in a single request
const versionDataMap = new Map<
string,
components['schemas']['NodeVersion']
>()
for (let i = 0; i < installedPacks.value.length; i += chunkSize) {
const chunk = installedPacks.value.slice(i, i + chunkSize)
// Prepare bulk request with actual installed versions from Manager API
const nodeVersions = installedPacksWithVersions.value.map((pack) => ({
node_id: pack.id,
version: pack.version
}))
const fetchTasks = chunk.map(async (pack) => {
// Use pack.id which should be the normalized ID from Registry
const packageId = pack.id || ''
const version = pack.latest_version?.version || 'latest'
if (nodeVersions.length > 0) {
try {
const bulkResponse = await registryService.getBulkNodeVersions(
nodeVersions,
abortController.value?.signal
)
try {
const versionData = await registryService.getPackByVersion(
packageId,
version,
abortController.value?.signal
)
if (versionData) {
versionDataMap.set(packageId, versionData)
}
} catch (error) {
console.warn(
`[ConflictDetection] Failed to fetch version data for ${packageId}@${version}:`,
error
)
if (bulkResponse && bulkResponse.node_versions) {
// Process bulk response
bulkResponse.node_versions.forEach((result) => {
if (result.status === 'success' && result.node_version) {
versionDataMap.set(
result.identifier.node_id,
result.node_version
)
} else if (result.status === 'error') {
console.warn(
`[ConflictDetection] Failed to fetch version data for ${result.identifier.node_id}@${result.identifier.version}:`,
result.error_message
)
}
})
}
})
await Promise.allSettled(fetchTasks)
} catch (error) {
console.warn(
'[ConflictDetection] Failed to fetch bulk version data:',
error
)
}
}
// Step 5: Combine local installation data with Registry version data
// Use installedPacks from useInstalledPacks composable
const requirements: NodePackRequirements[] = []
// Create a map for quick access to version info
const versionInfoMap = new Map(
installedPacksWithVersions.value.map((pack) => [pack.id, pack.version])
)
for (const pack of installedPacks.value) {
const packageId = pack.id || ''
const versionData = versionDataMap.get(packageId)
const installedVersion = versionInfoMap.get(packageId) || 'unknown'
// Check if package is enabled using store method
const isEnabled = managerStore.isPackEnabled(packageId)
@@ -265,7 +275,7 @@ export function useConflictDetection() {
// Basic package info
package_id: packageId,
package_name: pack.name || packageId,
installed_version: pack.latest_version?.version || 'unknown',
installed_version: installedVersion,
is_enabled: isEnabled,
// Version-specific compatibility data
@@ -297,7 +307,7 @@ export function useConflictDetection() {
const fallbackRequirement: NodePackRequirements = {
package_id: packageId,
package_name: pack.name || packageId,
installed_version: pack.latest_version?.version || 'unknown',
installed_version: installedVersion,
is_enabled: isEnabled,
is_banned: false,
registry_fetch_time: new Date().toISOString(),

View File

@@ -359,6 +359,55 @@ export const useComfyRegistryService = () => {
)
}
/**
* Get multiple pack versions in a single bulk request.
* This is more efficient than making individual requests for each pack version.
*
* @param nodeVersions - Array of node ID and version pairs to retrieve
* @param signal - Optional AbortSignal for request cancellation
* @returns Bulk response containing the requested node versions or null on error
*
* @example
* ```typescript
* const versions = await getBulkNodeVersions([
* { node_id: 'ComfyUI-Manager', version: '1.0.0' },
* { node_id: 'ComfyUI-Impact-Pack', version: '2.0.0' }
* ])
* if (versions) {
* versions.node_versions.forEach(result => {
* if (result.status === 'success' && result.node_version) {
* console.log(`Retrieved ${result.identifier.node_id}@${result.identifier.version}`)
* }
* })
* }
* ```
*/
const getBulkNodeVersions = async (
nodeVersions: components['schemas']['NodeVersionIdentifier'][],
signal?: AbortSignal
) => {
const endpoint = '/bulk/nodes/versions'
const errorContext = 'Failed to get bulk node versions'
const routeSpecificErrors = {
400: 'Bad request: Invalid node version identifiers provided'
}
const requestBody: components['schemas']['BulkNodeVersionsRequest'] = {
node_versions: nodeVersions
}
return executeApiRequest(
() =>
registryApiClient.post<
components['schemas']['BulkNodeVersionsResponse']
>(endpoint, requestBody, {
signal
}),
errorContext,
routeSpecificErrors
)
}
return {
isLoading,
error,
@@ -372,6 +421,7 @@ export const useComfyRegistryService = () => {
listPacksForPublisher,
getNodeDefs,
postPackReview,
inferPackFromNodeName
inferPackFromNodeName,
getBulkNodeVersions
}
}