[backport core/1.41] Cache execution id to node locator id mappings (#9244) (#10153)

Backport of #9244 to core/1.41.

Cherry-picked merge commit 5fe31e63e with conflict resolution in
`src/stores/executionStore.test.ts` (kept existing eviction tests from
#10060 backport alongside new cache tests).

This backport provides the `executionIdToLocatorCache` implementation
that #10060 (backport of #9249) expects in its tests.

┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-10153-backport-core-1-41-Cache-execution-id-to-node-locator-id-mappings-9244-3266d73d3650819782e2cd0770bd3353)
by [Unito](https://www.unito.io)

Co-authored-by: John Haugeland <stonecypher@gmail.com>
This commit is contained in:
Christian Byrne
2026-03-17 01:24:44 -07:00
committed by GitHub
parent 0a8e4b3012
commit e6d11df2f9
2 changed files with 21 additions and 2 deletions

View File

@@ -387,7 +387,6 @@ describe('useExecutionStore - nodeProgressStatesByJob eviction', () => {
expect(store.nodeProgressStatesByJob).toHaveProperty('job-0')
})
})
describe('useExecutionStore - reconcileInitializingJobs', () => {
let store: ReturnType<typeof useExecutionStore>

View File

@@ -80,6 +80,24 @@ export const useExecutionStore = defineStore('execution', () => {
const initializingJobIds = ref<Set<string>>(new Set())
/**
* Cache for executionIdToNodeLocatorId lookups.
* Avoids redundant graph traversals during a single execution run.
* Cleared at execution start and end to ensure fresh graph state.
*/
const executionIdToLocatorCache = new Map<string, NodeLocatorId | undefined>()
function cachedExecutionIdToLocator(
executionId: string
): NodeLocatorId | undefined {
if (executionIdToLocatorCache.has(executionId)) {
return executionIdToLocatorCache.get(executionId)
}
const locatorId = executionIdToNodeLocatorId(app.rootGraph, executionId)
executionIdToLocatorCache.set(executionId, locatorId)
return locatorId
}
const mergeExecutionProgressStates = (
currentState: NodeProgressState | undefined,
newState: NodeProgressState
@@ -119,7 +137,7 @@ export const useExecutionStore = defineStore('execution', () => {
const parts = String(state.display_node_id).split(':')
for (let i = 0; i < parts.length; i++) {
const executionId = parts.slice(0, i + 1).join(':')
const locatorId = executionIdToNodeLocatorId(app.rootGraph, executionId)
const locatorId = cachedExecutionIdToLocator(executionId)
if (!locatorId) continue
result[locatorId] = mergeExecutionProgressStates(
@@ -227,6 +245,7 @@ export const useExecutionStore = defineStore('execution', () => {
}
function handleExecutionStart(e: CustomEvent<ExecutionStartWsMessage>) {
executionIdToLocatorCache.clear()
executionErrorStore.clearAllErrors()
activeJobId.value = e.detail.prompt_id
queuedJobs.value[activeJobId.value] ??= { nodes: {} }
@@ -473,6 +492,7 @@ export const useExecutionStore = defineStore('execution', () => {
* Reset execution-related state after a run completes or is stopped.
*/
function resetExecutionState(jobIdParam?: string | null) {
executionIdToLocatorCache.clear()
nodeProgressStates.value = {}
const jobId = jobIdParam ?? activeJobId.value ?? null
if (jobId) {