forked from VOICEVOX/voicevox
-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
サードパーティがエンジンへのアクセス情報を得るための設定書き出し機能 (VOICEVOX#1765)
* 未対応エンジン追加時にリストが消える件(VOICEVOX#1168) ・追加されたエンジンが未対応である場合には追加を阻止 ・追加されてしまっている場合には、エラーで処理中断しないように * lintチェックエラー部分の修正 * コードレビューの反映 (ref VOICEVOX#1179) ・MinimumEngineManifestの更新 * コードレビュー分の反映② ref VOICEVOX#1179 ・engineManifests[selectedId]自体が undefined であるケースに対応 * サードパーティがエンジンへのアクセス情報を得るための設定書き出し機能(ref VOICEVOX#1738) * ファイルは runtime-info.json に書き出し * エンジン全起動もしくは個別起動/終了のタイミングで更新 * * 関数名の変更 : writeEngineInfoFor3rdParty * 排他ロックの追加 * 処理の非同期化 * * コンストラクタ引数でファイルパスを渡すように * 関数をシンプルに * ログメッセージ修正 * コメント位置修正 * * エクスポートファイパスを渡す所を引数にした * 変数、関数名修正 * いくつかの構造をクラス化 * 議論 VOICEVOX#1738 に基づき、最小項目の書き出しに変更 * * ファイル書き出しクラスに機能を集約 * 変数名、コメントの修正 * RuntimeInfoManager.tsをブラッシュアップ * EngineManagerとRuntimeInfoManagerを疎結合に * データ構造調整、テスト追加 * Apply suggestions from code review --------- Co-authored-by: Hiroshiba <[email protected]>
- Loading branch information
Showing
7 changed files
with
178 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,104 @@ | ||
/** | ||
* サードパーティ向けのランタイム情報を書き出す。 | ||
* ランタイム情報には起動しているエンジンのURLなどが含まれる。 | ||
*/ | ||
|
||
import fs from "fs"; | ||
import AsyncLock from "async-lock"; | ||
import log from "electron-log/main"; | ||
import { EngineId, EngineInfo } from "@/type/preload"; | ||
|
||
/** | ||
* ランタイム情報書き出しに必要なEngineInfo | ||
*/ | ||
export type EngineInfoForRuntimeInfo = Pick< | ||
EngineInfo, | ||
"uuid" | "host" | "name" | ||
>; | ||
|
||
/** | ||
* 保存されるランタイム情報 | ||
*/ | ||
type RuntimeInfo = { | ||
formatVersion: number; | ||
appVersion: string; | ||
engineInfos: { | ||
uuid: EngineId; | ||
url: string; | ||
name: string; | ||
}[]; | ||
}; | ||
|
||
/** | ||
* サードパーティ向けのランタイム情報を書き出す | ||
*/ | ||
export class RuntimeInfoManager { | ||
private runtimeInfoPath: string; | ||
private appVersion: string; | ||
|
||
constructor(runtimeInfoPath: string, appVersion: string) { | ||
this.runtimeInfoPath = runtimeInfoPath; | ||
this.appVersion = appVersion; | ||
} | ||
|
||
/** | ||
* ファイルロック用のインスタンス | ||
*/ | ||
private lock = new AsyncLock({ | ||
timeout: 1000, | ||
}); | ||
private lockKey = "write"; | ||
|
||
/** | ||
* ファイルフォーマットバージョン | ||
*/ | ||
private fileFormatVersion = 1; | ||
|
||
/** | ||
* エンジン情報(書き出し用に記憶) | ||
*/ | ||
private engineInfos: EngineInfoForRuntimeInfo[] = []; | ||
|
||
/** | ||
* エンジン情報を登録する | ||
*/ | ||
public setEngineInfos(engineInfos: EngineInfoForRuntimeInfo[]) { | ||
this.engineInfos = engineInfos; | ||
} | ||
|
||
/** | ||
* ランタイム情報ファイルを書き出す | ||
*/ | ||
public async exportFile() { | ||
await this.lock.acquire(this.lockKey, async () => { | ||
log.info( | ||
`Runtime information file has been updated. : ${this.runtimeInfoPath}` | ||
); | ||
|
||
// データ化 | ||
const runtimeInfoFormatFor3rdParty: RuntimeInfo = { | ||
formatVersion: this.fileFormatVersion, | ||
appVersion: this.appVersion, | ||
engineInfos: this.engineInfos.map((engineInfo) => { | ||
return { | ||
uuid: engineInfo.uuid, | ||
url: engineInfo.host, // NOTE: 元のEngineInfo.hostにURLが入っている | ||
name: engineInfo.name, | ||
}; | ||
}), | ||
}; | ||
|
||
// ファイル書き出し | ||
try { | ||
await fs.promises.writeFile( | ||
this.runtimeInfoPath, | ||
JSON.stringify(runtimeInfoFormatFor3rdParty) // FIXME: zod化する | ||
); | ||
} catch (e) { | ||
// ディスクの空き容量がない、他ツールからのファイルロック時をトラップ。 | ||
// サードパーティ向けなのでVOICEVOX側には通知せず、エラー記録して継続 | ||
log.error(`Failed to write file : ${e}`); | ||
} | ||
}); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
import { tmpdir } from "os"; | ||
import { join } from "path"; | ||
import fs from "fs"; | ||
import { expect, test } from "vitest"; | ||
import { EngineId } from "@/type/preload"; | ||
|
||
import { RuntimeInfoManager } from "@/background/RuntimeInfoManager"; | ||
|
||
test("想定通りのラインタイム情報が保存されている", async () => { | ||
const randomName = Math.random().toString(36).substring(7); | ||
const tempFilePath = join(tmpdir(), `runtime-info-${randomName}.json`); | ||
|
||
const appVersion = "999.999.999"; | ||
const runtimeInfoManager = new RuntimeInfoManager(tempFilePath, appVersion); | ||
|
||
// エンジン情報 | ||
runtimeInfoManager.setEngineInfos([ | ||
{ | ||
uuid: EngineId("00000000-0000-0000-0000-000000000001"), | ||
host: "https://example.com/engine1", | ||
name: "engine1", | ||
}, | ||
{ | ||
uuid: EngineId("00000000-0000-0000-0000-000000000002"), | ||
host: "https://example.com/engine2", | ||
name: "engine2", | ||
}, | ||
]); | ||
|
||
// ファイル書き出し | ||
await runtimeInfoManager.exportFile(); | ||
|
||
// ファイル読み込みしてスナップショットの比較 | ||
// NOTE: スナップショットが変わった場合、破壊的変更ならformatVersionを上げる | ||
const savedRuntimeInfo = JSON.parse(fs.readFileSync(tempFilePath, "utf-8")); | ||
expect(savedRuntimeInfo).toMatchInlineSnapshot(` | ||
{ | ||
"appVersion": "999.999.999", | ||
"engineInfos": [ | ||
{ | ||
"name": "engine1", | ||
"url": "https://example.com/engine1", | ||
"uuid": "00000000-0000-0000-0000-000000000001", | ||
}, | ||
{ | ||
"name": "engine2", | ||
"url": "https://example.com/engine2", | ||
"uuid": "00000000-0000-0000-0000-000000000002", | ||
}, | ||
], | ||
"formatVersion": 1, | ||
} | ||
`); | ||
}); |