Closed OzoneAsai closed 6 months ago
報告ありがとうございます。 辞書ファイルはuser.dicで1つであり、文字列処理が必要になる動作をしようとすると最初に辞書をコンパイルする動作が入るので、複数立ち上げようとすると、使用中の辞書に書き込もうとしてエラーが出るという状態ですね。このふるまいはあまり考えていませんでした。
対策は考えますが、どうすればいいのかすぐには分からないので、とりあえず同時に複数のものを立ち上げずに1つのもののみで使っていただけたらと思います。
コンパイル時のファイル名は任意のものを指定できないのですか?できるならuuid並みのランダムな文字列をファイルに入れましょう(?)
ファイル名は指定できますが、そうすると、プロセス終了時にそれをうまく削除しないと、辞書ファイルのコピーが大量にあふれてしまう問題があり、うまい解決策は見つけられないです。
普段よく見る.lck#みたいな気持ちで、プロセスが起動したら特定のファイルにPIDとそのプロセスが作成したファイルの名前を書き込んで、ほかのプロセスとして実行されたら特定のファイルに書き込まれたPIDが特定のファイルに書き込まれたプロセス名と一致するかどうか調べて、一致するものがなければコンパイルされた辞書ファイルを削除して新しく作成。一致するものがあれば、新しく作成。 というのはどうでしょうか? ChatGPTによる説明 この要求は、プロセスの実行を監視し、特定のファイルに関連情報を書き込んで管理する仕組みを説明しています。以下に、この仕組みを具体的なチャートで説明します。
プロセスの起動と監視
プロセスの実行の確認
辞書ファイルの管理
これにより、重複した辞書ファイルの参照や、強制終了されたプロセスによって作成された辞書ファイルの増加を防ぐことができます。
以下に、上記の内容を示すチャートを提供します:
プロセスの起動
|
↓
特定のファイルに
PIDとプロセス情報を書き込む
|
↓
プロセスの実行の確認
|
↓
特定のファイルからPIDを読み取る
|
↓
PIDとプロセス名の一致確認
|
↓
一致するものがない場合:
辞書ファイルの削除
新しい辞書ファイルを作成
一致するものがある場合:
新しい辞書ファイルを作成
このような仕組みによって、プロセスの管理と辞書ファイルの効率的な利用が実現されます。
提案ありがとうございます。プロセス管理やPIDやらロックについては全く知らないので、自分がちゃんとコードを書けるかは分からないです……。 しばらくバグ修正等他のことをやるので、どなたか実装していただけると非常に助かります。
お世話になっております。
まずは
などを正確に分析する必要がありそうです。 以下のように分析しました。間違っていたら申し訳ございません。
エディター と FastAPI、前処理など、同時に実行できないプロセスがある -> 後に起動したプロセスがuser.dicの書き込もうとするとエラー -> 先に起動したプロセスが既に開いている -> pyopenjtalkがプロセス実行中、オープンしている
コンパイル済みユーザー辞書ファイルuser.dicがプロセス間で共通であり、 最初に起動したプロセスがオープンし続けている おそらくpyopenjtalk -> openjtalk -> Mecab由来
最初に起動したプロセスがファイルをオープンし続けていることがネックです。思いついた以下の方法を提案させていただきます。
各プロセスが別名でコンパイル済みユーザー辞書を扱います。 Ex. server_editor.user.dic, server_fastapi.user.dic
ユースケースのため、辞書の内容は同期されるようにする必要があります。 これは何らかの方法で辞書変更イベントを監視する必要があります。 Ex. ファイルの変更
辞書の変更やrun_frontendなど、pyopenjtalkに関する処理を行う別プロセスで起動します。 Ex. pyopenjtalk_worker
プロセス間通信によってリクエストを送り、レスポンスを受け取ります。 Ex. 名前付きパイプ
ここで主なリクエストはpyopenjtalkのメソッドの引数、 レスポンスは戻り値です。
若干の実装のイメージもあります。 Ex. 既存のimport pyopenjtalkはimport pyopenjtalk as pyopenjtalk_workerにする
他にも方法はあると思いますが、どれがベストかは何とも言えません。 個人的には方法2ですが、一定の複雑さは出てしまうと思っています。 まだどこまで実装できるかわかりませんが、 ご意見ありましたらよろしくお願いいたします。
プロセス間通信の方法として、名前付きパイプを検討していましたが、 以下の問題がわかりました。
かわりにソケット通信で試してみます。
2.4.0にてワーカー化で対応することで解決されました。ご意見等ありがとうございました!