[Manager] Allow cancelling registry requests by route (#3158)

This commit is contained in:
Christian Byrne
2025-03-20 07:30:00 -07:00
committed by GitHub
parent afdb94f12f
commit c34cc301f1
3 changed files with 38 additions and 80 deletions

View File

@@ -18,7 +18,7 @@ export const useNodePacks = (
options: UseNodePacksOptions = {}
) => {
const { immediate = false, maxConcurrent = DEFAULT_MAX_CONCURRENT } = options
const { getPackById, cancelRequests } = useComfyRegistryStore()
const { getPackById } = useComfyRegistryStore()
const nodePacks = ref<NodePack[]>([])
const processedIds = ref<Set<string>>(new Set())
@@ -31,8 +31,8 @@ export const useNodePacks = (
remainingIds.value?.length ? chunk(remainingIds.value, maxConcurrent) : []
)
const fetchPack = (ids: Parameters<typeof getPackById>[0]) =>
ids ? getPackById(ids) : null
const fetchPack = (id: Parameters<typeof getPackById.call>[0]) =>
id ? getPackById.call(id) : null
const toRequestBatch = async (ids: string[]) =>
Promise.all(ids.map(fetchPack))
@@ -63,7 +63,7 @@ export const useNodePacks = (
}
const cleanup = () => {
cancelRequests()
getPackById.cancel()
clear()
}

View File

@@ -1,5 +1,4 @@
import { defineStore } from 'pinia'
import { computed, ref } from 'vue'
import { useCachedRequest } from '@/composables/useCachedRequest'
import { useComfyRegistryService } from '@/services/comfyRegistryService'
@@ -13,6 +12,7 @@ type ListPacksParams = operations['listAllNodes']['parameters']['query']
type ListPacksResult =
operations['listAllNodes']['responses'][200]['content']['application/json']
type ComfyNode = components['schemas']['ComfyNode']
type GetPackByIdPath = operations['getNode']['parameters']['path']['nodeId']
/**
* Store for managing remote custom nodes
@@ -20,85 +20,52 @@ type ComfyNode = components['schemas']['ComfyNode']
export const useComfyRegistryStore = defineStore('comfyRegistry', () => {
const registryService = useComfyRegistryService()
let listAllPacksHandler: ReturnType<
typeof useCachedRequest<ListPacksParams, ListPacksResult>
>
let getPackByIdHandler: ReturnType<typeof useCachedRequest<string, NodePack>>
let getNodeDefsHandler: ReturnType<
typeof useCachedRequest<{ packId: string; versionId: string }, ComfyNode[]>
>
const recentListResult = ref<NodePack[]>([])
const hasPacks = computed(() => recentListResult.value.length > 0)
/**
* Get a list of all node packs from the registry
*/
const listAllPacks = async (params: ListPacksParams) => {
listAllPacksHandler ??= useCachedRequest<ListPacksParams, ListPacksResult>(
registryService.listAllPacks,
{ maxSize: PACK_LIST_CACHE_SIZE }
)
const response = await listAllPacksHandler.call(params)
if (response) recentListResult.value = response.nodes || []
return response
}
const listAllPacks = useCachedRequest<ListPacksParams, ListPacksResult>(
registryService.listAllPacks,
{ maxSize: PACK_LIST_CACHE_SIZE }
)
/**
* Get a pack by its ID from the registry
*/
const getPackById = async (
packId: NodePack['id']
): Promise<NodePack | null> => {
if (!packId) return null
getPackByIdHandler ??= useCachedRequest<string, NodePack>(
registryService.getPackById,
{ maxSize: PACK_BY_ID_CACHE_SIZE }
)
return getPackByIdHandler.call(packId)
}
const getPackById = useCachedRequest<GetPackByIdPath, NodePack>(
async (params) => {
if (!params) return null
return registryService.getPackById(params)
},
{ maxSize: PACK_BY_ID_CACHE_SIZE }
)
/**
* Get the node definitions for a pack
*/
const getNodeDefs = async (
packId: NodePack['id'],
versionId: NonNullable<NodePack['latest_version']>['id']
) => {
if (!packId || !versionId) return null
getNodeDefsHandler ??= useCachedRequest<
{ packId: string; versionId: string },
ComfyNode[]
>(registryService.getNodeDefs, { maxSize: PACK_BY_ID_CACHE_SIZE })
return getNodeDefsHandler.call({ packId, versionId })
}
const getNodeDefs = useCachedRequest<
{ packId: string; versionId: string },
ComfyNode[]
>(registryService.getNodeDefs, { maxSize: PACK_BY_ID_CACHE_SIZE })
/**
* Clear all cached data
*/
const clearCache = () => {
listAllPacksHandler?.clear()
getPackByIdHandler?.clear()
getNodeDefs.clear()
listAllPacks.clear()
getPackById.clear()
}
/**
* Cancel any in-flight requests
* Cancel all any in-flight requests.
*/
const cancelRequests = () => {
listAllPacksHandler?.cancel()
getPackByIdHandler?.cancel()
getNodeDefs.cancel()
listAllPacks.cancel()
getPackById.cancel()
}
return {
recentListResult,
hasPacks,
listAllPacks,
getPackById,
getNodeDefs,

View File

@@ -1,5 +1,5 @@
import { createPinia, setActivePinia } from 'pinia'
import { beforeEach, describe, expect, it, vi } from 'vitest'
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
import { ref } from 'vue'
import { useComfyRegistryService } from '@/services/comfyRegistryService'
@@ -57,22 +57,17 @@ describe('useComfyRegistryStore', () => {
)
})
it('should initialize with empty state', () => {
const store = useComfyRegistryStore()
expect(store.recentListResult).toEqual([])
expect(store.hasPacks).toBe(false)
afterEach(() => {
useComfyRegistryStore().clearCache()
})
it('should fetch and store packs', async () => {
const store = useComfyRegistryStore()
const params = { page: 1, limit: 10 }
const result = await store.listAllPacks(params)
const result = await store.listAllPacks.call(params)
expect(result).toEqual(mockListResult)
expect(store.recentListResult).toEqual(mockListResult.nodes)
expect(store.hasPacks).toBe(true)
expect(mockRegistryService.listAllPacks).toHaveBeenCalledWith(
params,
expect.any(Object) // abort signal
@@ -89,29 +84,26 @@ describe('useComfyRegistryStore', () => {
mockRegistryService.listAllPacks.mockResolvedValueOnce(emptyResult)
const store = useComfyRegistryStore()
await store.listAllPacks({ page: 1, limit: 10 })
const result = await store.listAllPacks.call({ page: 1, limit: 10 })
expect(store.recentListResult).toEqual([])
expect(store.hasPacks).toBe(false)
expect(result).toEqual(emptyResult)
})
it('should fetch a pack by ID', async () => {
const store = useComfyRegistryStore()
const packId = 'test-pack-id'
const result = await store.getPackById(packId)
const result = await store.getPackById.call(packId)
expect(result).toEqual(mockNodePack)
expect(mockRegistryService.getPackById).toHaveBeenCalledWith(
packId,
expect.any(Object) // abort signal
)
expect(mockRegistryService.getPackById).toHaveBeenCalledWith(packId)
})
it('should return null when fetching a pack with null ID', async () => {
const store = useComfyRegistryStore()
vi.spyOn(store.getPackById, 'call').mockResolvedValueOnce(null)
const result = await store.getPackById(null as any)
const result = await store.getPackById.call(null as any)
expect(result).toBeNull()
expect(mockRegistryService.getPackById).not.toHaveBeenCalled()
@@ -121,9 +113,8 @@ describe('useComfyRegistryStore', () => {
mockRegistryService.listAllPacks.mockResolvedValueOnce(null)
const store = useComfyRegistryStore()
const result = await store.listAllPacks({ page: 1, limit: 10 })
const result = await store.listAllPacks.call({ page: 1, limit: 10 })
expect(result).toBeNull()
expect(store.recentListResult).toEqual([])
})
})