Skip to content
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

Linux上で外部からKillされたENGINEを再起動できない問題を修正 #286

Merged

Conversation

aoirint
Copy link
Member

@aoirint aoirint commented Sep 30, 2021

内容

#282 から分割しました。

Linux上で、ENGINEが外部からプロセスキルされると、
VOICEVOXのUI上で「エンジンの再起動」操作(RESTART_ENGINE)が終了しない問題を修正します。

現在 5488b92 のロジックである engineProcess.exitCode !=== null のみでは、child_processを使って起動されたENGINEのプロセスが終了しているかどうかを完全には判定できません。

例えば、 kill $PID でENGINEがプロセスキルされたとき、exitCode === null にもかかわらず、ENGINE のプロセスは終了しているという状態になります。

このとき、RESTART_ENGINEでは、すでに終了しているENGINEのプロセスをkillしようとする動作をします。
killされているプロセスをkillしようとしても、ChildProcessの close イベントが起こらないため、起動処理 runEngine() が実行されず、「再起動」が終了しません。

ENGINEがプロセスキルされたとき、signalCode は設定されるため、
signalCode !== null を合わせてチェックすることで、この問題を修正します。

実験

#281 で追加した process.on("close", ...) でのログ出力で、exitCode、signalCodeの挙動を確認してみました。

  • Windows(taskkill /F /PID $PID、タスクマネージャ タスクの終了)
    • ケース1: uvicorn起動前
      • exitCode: 1
      • signalCode: null
    • ケース2: uvicorn(runのHTTPサーバ)起動後
      • exitCode: 1
      • signalCode: null
  • Ubuntu(kill $PID
    • ケース3: uvicorn起動前
      • exitCode: null
      • signalCode: SIGTERM
        • プロセスをkillしたあと、UIからエンジンを再起動しようとしたときにも、exitCode/signalCodeは変わらなかった
    • ケース4: uvicorn起動後
      • exitCode: 0
      • signalCode: null

ケース3では、VOICEVOXのUIからの「エンジンの再起動」操作(RESTART_ENGINE)が終了しなくなるという問題が起きます。

再現の流れ

  1. VOICEVOXを起動する
    • 自動的にENGINEの起動が始まる
  2. ENGINEのHTTPサーバが起動する前に、kill $PID でENGINEをプロセスキルする
  3. VOICEVOXのUI上で「エンジンの再起動」(RESTART_ENGINE)操作をする
  4. 「エンジン起動中・・・」が表示される(ENGINEをkillしようと試みる)
    • ENGINEはすでにkillされている
    • プロセスがすでに終了しているため、ChildProcessの close イベントが起こらない
    • runEngine() が実行されない
  5. 「エンジンの再起動」操作が終わらない
    • エンジンの再起動には、VOICEVOXを終了し、再起動する必要がある

ケース3が起きる状況の例

  • killコマンド kill $PID
  • OOM Killer(OS側のメモリ確保機能、挙動はよくわからない)

関連 Issue

ref #282
ref #270
ref #218

@aoirint aoirint changed the title Linux上で外部からKillされたENGINEの再起動が終了しなくなる問題を修正 Linux上で外部からKillされたENGINEの再起動が終了しない問題を修正 Sep 30, 2021
@aoirint aoirint changed the title Linux上で外部からKillされたENGINEの再起動が終了しない問題を修正 Linux上で外部からKillされたENGINEを再起動できない問題を修正 Sep 30, 2021
Copy link
Member

@Hiroshiba Hiroshiba left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

調査ありがとうございます!!

killedを見ないといけないのはよくわかりました!(そもそもやっぱりexitCodeがなぜか来ない理由が気になりますが。。)
ただ、signalCode !== nullが別のバグの原因になるのを懸念している感じです。

例えばありそうなストーリーとしては、パソコンをスリープしたときにSIGSTOPとSIGCONTが実行されるようになっていて、スリープ後だとsignalCodeにはSIGCONTが入っていてエンジン再起動ができない、みたいなことが考えられるかなと思っています。

難しいところですが、いったんこの方式でやってみて反応を見てみても良いかなと思いました!
ということでLTGM!

@Hiroshiba Hiroshiba merged commit 4fa6f19 into VOICEVOX:main Oct 1, 2021
@aoirint aoirint deleted the patch-linux-restart-engine-after-killed branch February 28, 2022 00:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants