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

View File

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

View File

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