fix(tokenizer): avoid repeated yomitan anki sync checks on no-change

This commit is contained in:
2026-03-02 01:36:22 -08:00
parent 7161fc3513
commit cde231b1ff
4 changed files with 18 additions and 9 deletions

View File

@@ -4,7 +4,7 @@ title: 'Tokenization performance: disable Yomitan MeCab parser, gate local MeCab
status: Done status: Done
assignee: [] assignee: []
created_date: '2026-03-02 07:44' created_date: '2026-03-02 07:44'
updated_date: '2026-03-02 09:20' updated_date: '2026-03-02 20:34'
labels: [] labels: []
dependencies: [] dependencies: []
priority: high priority: high
@@ -45,6 +45,8 @@ Implemented tokenizer latency optimizations:
- added regression tests for Yomitan parse flag, MeCab warmup gating, and persistent/idle lifecycle behavior; - added regression tests for Yomitan parse flag, MeCab warmup gating, and persistent/idle lifecycle behavior;
- fixed tokenization warmup gate so first-use warmup completion is sticky (`tokenizationWarmupCompleted`) and sequential `tokenizeSubtitle` calls no longer re-run Yomitan/dictionary warmup path; - fixed tokenization warmup gate so first-use warmup completion is sticky (`tokenizationWarmupCompleted`) and sequential `tokenizeSubtitle` calls no longer re-run Yomitan/dictionary warmup path;
- added regression coverage in `src/main/runtime/composers/mpv-runtime-composer.test.ts` for sequential tokenize calls (`warmup` side effects run once); - added regression coverage in `src/main/runtime/composers/mpv-runtime-composer.test.ts` for sequential tokenize calls (`warmup` side effects run once);
- post-review critical fix: treat Yomitan default-profile Anki server sync `no-change` as successful check, so `lastSyncedYomitanAnkiServer` is cached and expensive sync checks do not repeat on every subtitle line;
- added regression assertion in `src/core/services/tokenizer/yomitan-parser-runtime.test.ts` for `updated: false` path returning sync success;
- validated with targeted tests and `tsc --noEmit`. - validated with targeted tests and `tsc --noEmit`.
<!-- SECTION:FINAL_SUMMARY:END --> <!-- SECTION:FINAL_SUMMARY:END -->

View File

@@ -44,15 +44,19 @@ test('syncYomitanDefaultAnkiServer updates default profile server when script re
assert.equal(infoLogs.length, 1); assert.equal(infoLogs.length, 1);
}); });
test('syncYomitanDefaultAnkiServer returns false when script reports no change', async () => { test('syncYomitanDefaultAnkiServer returns true when script reports no change', async () => {
const deps = createDeps(async () => ({ updated: false })); const deps = createDeps(async () => ({ updated: false }));
let infoLogCount = 0;
const updated = await syncYomitanDefaultAnkiServer('http://127.0.0.1:8766', deps, { const synced = await syncYomitanDefaultAnkiServer('http://127.0.0.1:8766', deps, {
error: () => undefined, error: () => undefined,
info: () => undefined, info: () => {
infoLogCount += 1;
},
}); });
assert.equal(updated, false); assert.equal(synced, true);
assert.equal(infoLogCount, 0);
}); });
test('syncYomitanDefaultAnkiServer logs and returns false on script failure', async () => { test('syncYomitanDefaultAnkiServer logs and returns false on script failure', async () => {

View File

@@ -846,7 +846,11 @@ export async function syncYomitanDefaultAnkiServer(
logger.info?.(`Updated Yomitan default profile Anki server to ${normalizedTargetServer}`); logger.info?.(`Updated Yomitan default profile Anki server to ${normalizedTargetServer}`);
return true; return true;
} }
return false; const checkedWithoutUpdate =
typeof result === 'object' &&
result !== null &&
(result as { updated?: unknown }).updated === false;
return checkedWithoutUpdate;
} catch (err) { } catch (err) {
logger.error('Failed to sync Yomitan default profile Anki server:', (err as Error).message); logger.error('Failed to sync Yomitan default profile Anki server:', (err as Error).message);
return false; return false;

View File

@@ -2627,7 +2627,7 @@ async function syncYomitanDefaultProfileAnkiServer(): Promise<void> {
return; return;
} }
const updated = await syncYomitanDefaultAnkiServerCore( const synced = await syncYomitanDefaultAnkiServerCore(
targetUrl, targetUrl,
{ {
getYomitanExt: () => appState.yomitanExt, getYomitanExt: () => appState.yomitanExt,
@@ -2654,8 +2654,7 @@ async function syncYomitanDefaultProfileAnkiServer(): Promise<void> {
}, },
); );
if (updated) { if (synced) {
logger.info(`Yomitan default profile Anki server set to ${targetUrl}`);
lastSyncedYomitanAnkiServer = targetUrl; lastSyncedYomitanAnkiServer = targetUrl;
} }
} }