-
Notifications
You must be signed in to change notification settings - Fork 204
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
API・routers と 機能マネージャに関するアーキテクチャ #1449
Comments
👍️ |
なるほどです、ありがとうございます!! 今のrouterと内部の機能は分ける方針は、実態にうまく刺さってると感じます。 |
以下具体案と検討点の続き。 VOICEVOX ENGINE は機能が充実・複雑化し APIs の数も増大している。現段階で 40 以上の API が定義されている。 3 点目として以下の意見に同意か否かを確認したいです: Q3: API 数を鑑みて「API を複数のルーターへ分割する」アーキテクチャを採用すべきである このアーキテクチャを採用する場合、 4 点目として以下の認識確認がしたいです: Q4: 「API インスタンスを複数の用途に用いる前提」は共通認識として良いか否か この前提に従うと、 5 点目として以下の意見に同意か否かを確認したいです: Q5: 引数の数と機能的凝集を鑑みて「 |
こちら賛成です!
これちょっと問いの内容を正確にわかってないのですが、多分提言したいのは導かれる結果の方で、この2点ですよね 👀
僕もトレーニングかねて考えてみたんですが、どう考えればいいのかすごい難しいですね。。 各routerとapplication(generate_app)を分けたくなるのはおそらくテストだけだと感じます。 一方で機能マネージャーをDIするかに関して、そもそもマネージャーに役割が3つありそうに感じました。 論点にあげたいのが3つ目に関してで、別にそのマネージャーを使ったテストがしたいわけではなく、routerを超えて状態を保持したいだけなのであれば、 ちょっと話はそれちゃうのですが、この場合設定からマネージャを作る場所が複数個コピペになっちゃう問題はあると思います。(↑の3つの役割の1つ目)
前述の通り、「すべき」かは置いといて「メンテコストとの兼ね合いでそういうのもあり」とは思います! |
ニュアンスとしては「共有変数
これに似た観点として「完璧に設計できない限り不安定さを増す」が挙げられると考えます。 上記の議論を正しく進めるには Q4': 「 各機能マネージャーが 3 役割のどこまで担うか明確かつそれが安定であるなら、Q4' の想定を置く必要はないと考えます。 |
質問を質問で返してしまうのですが(すみません 🙇 )、generate_appの複数用途というのはどういう意味でしょうか・・・? 「各機能マネージャの複数の用途」もちゃんとわかってないかもです。 「generate_app内でクラスのインスタンスを作るのはとりあえずダメ!generate_appの外で作る!理由は実装を統一させるため!」とかならわかります。 |
いえいえ、アーキテクチャの議論は忌憚無い意見が重要ですので、遠慮なく不明瞭点・不明点は指摘して頂ければ🙏
👍️
こちらは「
Q4' の後半は「A の想定で良いか」という意味合いです。 各機能マネージャーの用途範囲(『VOICEVOX ENGINE 生成』『E2E テスト』『docs 生成』等のどれまで責務があるか)が明確かつそれが安定であるなら、Q4' の想定を置く必要はないと考えます。B のように、
ここの自信の源泉となるロジックを積み上げている形です。 |
なるほどです!! いろんな機能マネージャーをDIする形は賛成なのですが、その理由が「いろんな用途に使われるから」だという部分に違和感がありました。 なので多分言葉尻を微調整してこんな感じかなと。 この言い回しの感じで認識が一緒、あるいは言ってることは一緒っぽかったらOK だと思います!! 考え方勉強になりました、ありがとうございます 🙇 |
👍️ どの前提を置くかはプロジェクトの方針次第なので「用途範囲がいずれ明確化しうる」という前提に同意です。 現時点で合意が取れたアーキテクチャをまとめます: アーキテクチャ @ 2024-07-04VOICEVOX ENGINE は機能が充実し 40 以上の API を定義している。よって『APIs をルーターモジュールへ分割』するアーキテクチャを採用する。ルーターは生成された後に 1 つの APIs インスタンスへ合体される。 機能の複雑化によりルーターと機能マネージャは 1:1 対応していない。よって『ルーターモジュールから機能マネージャの定義・生成を分離』するアーキテクチャを採用する。 APIs インスタンスはサービス提供・テスト・ドキュメント生成等の複数用途で利用される。機能マネージャごとにこれら用途全てを担うか一部のみを担うかは異なるが、現時点で用途範囲は不明確である。不明確なあいだは広い用途に対応可能であるのが望ましい。よって『ルーター生成・APIs 生成と機能マネージャ生成を DI で分離』するアーキテクチャを採用する。 以下、アーキテクチャ検討の続き。 上記アーキテクチャにより、VOICEVOX ENGINE は以下の 3 レイヤーに分離された:
依存関係は以下の通り:
A は ENGINE が担う処理の実体であり ENGINE の中核である。B は A の中核機能を外部へ提供するための変換レイヤー・インターフェースレイヤーである。C は APIs を WebAPI としてユーザーへ提供する最外層である。 しかし現在の VOICEVOX ENGINE レポジトリではモジュール・ファイルが以下のように散在している:
そのためレポジトリからレイヤー構造が読み取れない。すなわちレイヤー構造がディレクトリ構造へ反映できていない。
これにより一目で 3 層がわかり、見通しが改善する。またレビュー時に「 このような背景から、レイヤー構造(アーキテクチャ)を共通認識としこれをディレクトリ構造へ反映することを提案します。 |
現状のまとめありがとうございます! ディレクトリ分けるのは賛成です! ちょっと抽象度が高いですが、 考えたのですが、役割は「機能を置いておきたい」というより「apiコントローラ以外をまとめときたい」なのかな〜と思いました。 あと |
👍️
Python の言語仕様として
他に良さそうな名前となると、中々悩みますね。
|
ニュアンスわかります。
おーーー!!!ありがとうございます!! business_logicsがまさしくなのですが、まあ伝わら無さそうですよねぇ。。。いわゆるビジネスじゃないので。。。(もちろんそういうことではないのですが) んーーーーーー!!! 追記:違いました、レイヤードアーキテクチャにおけるdomainはビジネスロジックでした 😇 |
👍️ 他のモジュールはどういう名称が相応しいでしょうか?
上記アーキテクチャにより、機能マネージャの定義は Lines 390 to 395 in abcfa78
voicevox_engine/tools/make_docs.py Lines 60 to 66 in abcfa78
voicevox_engine/test/e2e/conftest.py Lines 68 to 70 in abcfa78
voicevox_engine/test/benchmark/engine_preparation.py Lines 30 to 38 in abcfa78
これらの箇所では共通して「設定値の取得 → 設定を反映したインスタンスの生成 → 設定値に基づくインスタンス生成は このような背景から、インスタンス生成を |
apiにするの賛成です! あーーーでも
集約には賛成です!場所も |
domain の外にあるユースケース寄りの層を application と呼ぶのはわりと一般的かと思います。
レイヤードアーキテクチャでどう呼ぶかは寡聞にして知らないです🙏(Layerd はレトロニウム寄りなため語彙が整理されていない印象はある)
なんとも微妙なとこですね。application 層が登場する場合は domain-application-presentaion と割っているのが恐らく一般的で、現
👍️
configs は機能マネージャーの設定を全部まとめたものなので(注記: ここでいう "configs" は ENGINE 引数・環境変数そのものとは異なる)、 domain に責務があり domain が正しい置き場所と考えます。application 層・presentation 層・起動方式がどうなっても configs は不変です。
|
あーーーーなるほどです。2つになっている状況、たしかに。
ありえるとしたら、WebAPIをAWSにデプロイするコマンドとか、デバッグ用にTTSできるUIとか、UIコンポーネントの提供くらいだと思うので、「アプリケーション」との衝突は無いとは思います!
実装コストとの兼ね合いは置いといて理想論でいうと、configsは任意のdomainの情報にアクセスすることになるので、domainとは層が別な気はちょっとします。
そのつもりだったのですが、思っていることと違うことに気づきました 🙇 🙇 まとまってないのですが、もしかしたらconfigの型・configのデフォルト値・ |
👍️
👍️
「組み立て」的な関数やクラスを集めたモジュールを作る、というニュアンスでしょうか? |
賛成です!
助かります!!! 始まりは、便利になるからというのもそうですが、そういうレイヤーがあるように感じる感じです! わかりやすいのがconfigsで、例えばdomain AがBどちらかを選択する設定があった場合、domainではなく使う側の責務に感じます。 あとは、domainに使わずにappだけに使うconfigが出てきたときに困るかも・・・? 層をまたぐデータ変換をデータトランスファー層として扱う設計を見かけたことがあります。 ・・・・・普通のサービスだとサービス起動方法はユーザーに露出しないけど、VOICEVOX ENGINEは実行もサービスの1つなので、実行レイヤーが考えられる、みたいな感じかも・・・? いやちょっとこじつけかな・・・。 |
👍️
とあったとき、下層のサブドメインを統括し単一の domain へまとめ上げるのが
👍️
API 数が少ない場合、API 定義は個別ルーターモジュールではなく
(デフォルト値・デフォルト config の置き場所はさておき、) |
generate_appは仰るとおりappにあって良さそうに感じました! generate_all_domainはdomain直下にあるのはどっちかというと少し不自然に思います。 起動周りをまとめるrunnerレイヤー(名前は説明のために適当につけました)もちょっと考えを進めてみました! 有用性は2点で、使う側(ユーザー・テスト・ドキュメント作成)に合わせて設計できるのと、使う側→domain→app→使う側のデータ変換部分の設計を柔軟に組めることだと思います。 提案ですが、どういう設計が良いのかはまだ資料が集まっておらず、正確な結論が出せない気がします。 という方針で良さそうであれば、ぜひ続きをお願いしたいです!! 🙏 |
本 Issue は直近 30 日間で活動がありません。今後の方針について VOICEVOX チームによる再検討がおこなわれる予定です。 |
内容
概要: API・routers と 機能マネージャに関するアーキテクチャの共通認識を得たい
VOICEVOX ENGINE の長期的な発展を目指して、設計(アーキテクチャ)の必要性が複数の issue / PRs で指摘されている。その中でも最上層に近い「API・routers と 機能マネージャ」に関して 1 つのアーキテクチャの方向性が仮説としてあり、これが妥当か否か・どこまで共通認識でどこから議論が必要かを検討したい。
以下具体案と検討点。
VOICEVOX ENGINE は機能が充実・複雑化しており、APIルーターと機能マネージャが 1:1 対応しない前提を取っている。下図に示すように、現段階で既に 1:1 対応していない。
まず 1 点目として以下の認識確認がしたいです:
Q1:
APIルーターと機能マネージャが 1:1 対応しない前提
は共通認識として良いか否かこの前提に立つと、API ルーターを定義するモジュール内では機能マネージャを定義・管理すべきでない(例:
routers.tts_pipeline
内でTTSEngineManager
は定義・インスタンス化すべきでない)。マネージャの定義場所を決めるルールが難しくなるし、マネージャの利用状況次第で定義場所を変えなくてはならなくなるし、circular dependency に気を配り続けなければいけなくなるからである。この制約によりアーキテクチャとして「API モジュールと機能モジュールの分離」が要請される。
2 点目として以下の意見に同意か否かを確認したいです:
Q2: 1:1 対応しない前提に基づき「API モジュールと機能モジュールの分離」アーキテクチャを採用すべきである
この 2 点はほぼ全てのディレクトリ構造やクラス定義場所に影響する、アーキテクチャ上の重要な論点と認識しています。
コントリビューターの皆さん(特に @Hiroshiba さん)の意見を伺えれば幸いです。
The text was updated successfully, but these errors were encountered: