refactor workflow model cache handling

This commit is contained in:
Dariusz L
2026-08-05 15:08:05 +02:00
parent f1cdfcdbd6
commit b9cf600cc6
2 changed files with 101 additions and 29 deletions
@@ -2349,6 +2349,73 @@ test('cached Missing Models refresh preserves browser geometry after linking a l
]);
});
test('workflow analysis and loaded model caches stay independent and cloned', () => {
const saveWorkflowModelCache = eval(
`(${extractMethod(workflowStateMethodsSource, 'saveWorkflowModelCache')})`
);
const restoreWorkflowModelCache = eval(
`(${extractMethod(workflowStateMethodsSource, 'restoreWorkflowModelCache')})`
);
const saveAnalysisCacheForActiveWorkflow = eval(
`(${extractMethod(workflowStateMethodsSource, 'saveAnalysisCacheForActiveWorkflow')})`
);
const restoreAnalysisCacheForActiveWorkflow = eval(
`(${extractMethod(workflowStateMethodsSource, 'restoreAnalysisCacheForActiveWorkflow')})`
);
const saveLoadedModelsCacheForActiveWorkflow = eval(
`(${extractMethod(workflowStateMethodsSource, 'saveLoadedModelsCacheForActiveWorkflow')})`
);
const restoreLoadedModelsCacheForActiveWorkflow = eval(
`(${extractMethod(workflowStateMethodsSource, 'restoreLoadedModelsCacheForActiveWorkflow')})`
);
const dialog = {
workflowKey: 'workflow-a\nsignature-a',
workflowAnalysisCaches: new Map(),
workflowLoadedModelCaches: new Map(),
cachedWorkflowSignature: 'analysis-signature',
cachedAnalysisData: { missing_models: [{ filename: 'missing.safetensors' }] },
cachedLoadedModelsSignature: 'loaded-signature',
cachedLoadedModelsData: { loaded_models: [{ filename: 'loaded.safetensors' }] },
getWorkflowScopedQueueKey() {
return this.workflowKey;
},
saveWorkflowModelCache,
restoreWorkflowModelCache,
cloneAnalysisData(data) {
return JSON.parse(JSON.stringify(data));
},
};
saveAnalysisCacheForActiveWorkflow.call(dialog);
saveLoadedModelsCacheForActiveWorkflow.call(dialog);
dialog.cachedAnalysisData.missing_models[0].filename = 'changed-analysis.safetensors';
dialog.cachedLoadedModelsData.loaded_models[0].filename = 'changed-loaded.safetensors';
assert.equal(
dialog.workflowAnalysisCaches.get(dialog.workflowKey).data.missing_models[0].filename,
'missing.safetensors'
);
assert.equal(
dialog.workflowLoadedModelCaches.get(dialog.workflowKey).data.loaded_models[0].filename,
'loaded.safetensors'
);
dialog.cachedWorkflowSignature = null;
dialog.cachedAnalysisData = null;
dialog.cachedLoadedModelsSignature = null;
dialog.cachedLoadedModelsData = null;
restoreAnalysisCacheForActiveWorkflow.call(dialog);
restoreLoadedModelsCacheForActiveWorkflow.call(dialog);
assert.equal(dialog.cachedWorkflowSignature, 'analysis-signature');
assert.equal(dialog.cachedLoadedModelsSignature, 'loaded-signature');
assert.equal(dialog.cachedAnalysisData.missing_models[0].filename, 'missing.safetensors');
assert.equal(dialog.cachedLoadedModelsData.loaded_models[0].filename, 'loaded.safetensors');
dialog.cachedAnalysisData.missing_models.push({ filename: 'local-only.safetensors' });
assert.equal(dialog.workflowAnalysisCaches.get(dialog.workflowKey).data.missing_models.length, 1);
});
test('node widget changes request a content-preserving Missing Models refresh', async () => {
const log = { debug() {} };
const refreshForActiveWorkflowChange = eval(
+34 -29
View File
@@ -463,50 +463,55 @@ export const workflowStateMethods = {
}
},
saveAnalysisCacheForActiveWorkflow() {
saveWorkflowModelCache(cache, signature, data) {
const key = this.getWorkflowScopedQueueKey();
if (!key) return;
if (this.cachedWorkflowSignature && this.cachedAnalysisData) {
this.workflowAnalysisCaches.set(key, {
signature: this.cachedWorkflowSignature,
data: this.cloneAnalysisData(this.cachedAnalysisData)
if (signature && data) {
cache.set(key, {
signature,
data: this.cloneAnalysisData(data)
});
} else {
this.workflowAnalysisCaches.delete(key);
cache.delete(key);
}
},
restoreWorkflowModelCache(cache) {
const key = this.getWorkflowScopedQueueKey();
const saved = key ? cache.get(key) : null;
return {
signature: saved?.signature || null,
data: saved?.data ? this.cloneAnalysisData(saved.data) : null
};
},
saveAnalysisCacheForActiveWorkflow() {
this.saveWorkflowModelCache(
this.workflowAnalysisCaches,
this.cachedWorkflowSignature,
this.cachedAnalysisData
);
},
restoreAnalysisCacheForActiveWorkflow() {
const key = this.getWorkflowScopedQueueKey();
const saved = key ? this.workflowAnalysisCaches.get(key) : null;
this.cachedWorkflowSignature = saved?.signature || null;
this.cachedAnalysisData = saved?.data
? this.cloneAnalysisData(saved.data)
: null;
const saved = this.restoreWorkflowModelCache(this.workflowAnalysisCaches);
this.cachedWorkflowSignature = saved.signature;
this.cachedAnalysisData = saved.data;
},
saveLoadedModelsCacheForActiveWorkflow() {
const key = this.getWorkflowScopedQueueKey();
if (!key) return;
if (this.cachedLoadedModelsSignature && this.cachedLoadedModelsData) {
this.workflowLoadedModelCaches.set(key, {
signature: this.cachedLoadedModelsSignature,
data: this.cloneAnalysisData(this.cachedLoadedModelsData)
});
} else {
this.workflowLoadedModelCaches.delete(key);
}
this.saveWorkflowModelCache(
this.workflowLoadedModelCaches,
this.cachedLoadedModelsSignature,
this.cachedLoadedModelsData
);
},
restoreLoadedModelsCacheForActiveWorkflow() {
const key = this.getWorkflowScopedQueueKey();
const saved = key ? this.workflowLoadedModelCaches.get(key) : null;
this.cachedLoadedModelsSignature = saved?.signature || null;
this.cachedLoadedModelsData = saved?.data
? this.cloneAnalysisData(saved.data)
: null;
const saved = this.restoreWorkflowModelCache(this.workflowLoadedModelCaches);
this.cachedLoadedModelsSignature = saved.signature;
this.cachedLoadedModelsData = saved.data;
},
invalidateLoadedModelsCacheForActiveWorkflow() {