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

エンジン再起動時にTCPの状態が CLOSE_WAIT のときに, そのタイムアウトを待つ #1326

Closed
wappon28dev opened this issue May 27, 2023 · 8 comments

Comments

@wappon28dev
Copy link
Contributor

良い Issue のタイトルが思いつかなかった…

内容

あらすじ

#1317 にて, エンジンの起動ポートが既に割り当てられている場合, 代替ポートで起動するようになりました.
また, エディターの終了後すぐに起動すると, ポートが TIME_WAIT になっているので, そのときはWindows のみ,
ポートが割り当てられていると判断しないようにしました.

課題

エンジンモード (CPU ⇄ GPU) の切り替え時に伴ってエンジンが再起動するときのみ, 一瞬 CLOSE_WAIT
なるので, エンジンの起動ポートが変更されるようです. しかし, メニューボタンから
エンジンの再起動を行なった場合, ポートの変更は行われなかったようです.

Pros 良くなる点

余計なポート変更を避けられる

Cons 悪くなる点

  • CLOSE_WAIT のタイムアウトを待つ (後述) ので直接影響はしないが, いわば “割り当て可能である” 条件を
    広くするので誤判断に気をつける必要があるかも…?

実現方法

  • CLOSE_WAIT のとき, CLOSE になる (or 割り当て可能になる) まで, タイムアウト付きで待機する.
    または,
  • エンジンモードの切り替え時のみ, ポートが変更されるので, 通常のエンジン再起動の時との処理の差を見つける.
    (ヒホさんも私も見つけられなかったですが… )

VOICEVOXのバージョン

#1317 より

OSの種類/ディストリ/バージョン

  • Windows のみ

その他

参考資料
  • TCPポートの状態遷移図1

  • それぞれの定義2
    • TIME_WAIT
       「CLOSING」でACKを受けた状態。アクティブ・クローズ後のタイムアウト待ち状態。同じシーケンス番号やポート番号などを再利用しないように、しばらく待ってから(ネットワーク上で遅れていたパケットがこの時間内に到着する可能性があるので、それと衝突しないように待つ)、「CLOSED」へ遷移して終了する。
    • CLOSE_WAIT
       パッシブ・クローズの状態。送信側にFINを送信して「LAST_ACK」へ遷移する。

Footnotes

  1. 信頼性のある通信を実現するTCPプロトコル - @​IT より

  2. TPCの仕組み - Qiita より

@Hiroshiba
Copy link
Member

issue作成ありがとうございます!!
個人的には

CLOSE_WAIT のとき, CLOSE になる (or 割り当て可能になる) まで, タイムアウト付きで待機する.

が良さそうに思いました!

現状のコード的に実現が難しそうだった場合は、エンジンをrestartする際、終了してからちょっと待って起動開始する処理に変えるのもありかもと思いました!

どんな環境でもCPU/GPU切り替えで起こる現象なのか不明ですが、もしそうだった場合は少し影響が大きそうなので、優先度を中に設定してみました。

@sabonerune
Copy link
Contributor

自分の環境でもエンジンを再起動したとき時々代替ポートに切り替わる現象が起こりました。
ただ、もしかしたらこのissueとは別の問題かもしれません。
netstatの出力の一部はこのようになっていました。
注: エンジンのポートは50022

  TCP         127.0.0.1:50022        127.0.0.1:51877        FIN_WAIT_2      3208
  TCP         127.0.0.1:50022        127.0.0.1:51878        FIN_WAIT_2      3208
  TCP         127.0.0.1:50022        127.0.0.1:51881        FIN_WAIT_2      3208
  TCP         127.0.0.1:50022        127.0.0.1:51882        FIN_WAIT_2      3208
  TCP         127.0.0.1:50022        127.0.0.1:51883        FIN_WAIT_2      3208
  TCP         127.0.0.1:50022        127.0.0.1:51884        FIN_WAIT_2      3208

少し実験してみたのですが外部アドレスの方が0.0.0.0:0(ipv6の場合[::]:0)ではない場合はそのままサーバーが立てられるようです。

@Hiroshiba
Copy link
Member

Hiroshiba commented May 30, 2023

僕も再度確認してみたのですが、再起動時にFIN_WAIT_2が出ていました!

  TCP         127.0.0.1:50021        127.0.0.1:60162        FIN_WAIT_2      11972

CLOSE_WAITも再確認してみたところ、これが出るのは、その・・・右?のhostが50021のときでした。

  TCP         127.0.0.1:60162        127.0.0.1:50021        CLOSE_WAIT      28656

いろいろ調べてみて完全に理解しました!!
そもそもFIN_WAIT_2とかCLOSE_WAITとかは特定のコネクションでの話であって、ポートが空いてるかどうかを判断したいならLISTENING状態のものだけ見れば良さそうだとわかりました!

実際今のVOICEVOXのコードを見ると、Linuxの場合はLINSTENステートだけをlsofしていそうです!
Windowsの場合もLISTENINGステートだけ見れば良いと思います!!

@wappon28dev
Copy link
Contributor Author

wappon28dev commented Jun 1, 2023

なるほど!!!
FIN_WAIT 以降は, あくまで FIN をサーバー側に返してから, サーバーの ACK/FIN 待つので,
ポートが割り当てられるかは, FIN_WAIT の時点でできると判定すれば良いということですね!

こちら, https://github.com/VOICEVOX/voicevox/pull/1317/files#diff-def518e538d6e3fe3d0320fa3a6ffd0d259b575e2a76b63f668482e737e16f16R53-R56LISTENING だけ含むようにすれば良いですかね?
(SYN_SENTSYN_RECEIVED, ESTABLISHED はどうしましょうか…?)

参考画像

1

Footnotes

  1. TCP状態遷移の解説 - hirota.noの技術ブログ より

@sabonerune
Copy link
Contributor

LISTENINGになっている接続は通信を受け付けるだけで新しく作成された接続(外部ポートが0.0.0.0:0ではないもの)がESTABLISHED等になるというのが自分の認識です。

なのでLISTENING以外のものは気にする必要はないと思います。

@Hiroshiba
Copy link
Member

Hiroshiba commented Jun 1, 2023

ですね!!

listeningはそのポートで待ってるサーバーがいることを意味してるはず。
それ以外の状態はハンドシェイクした2者間の状態を表してて、もうプロセス同士がハンドシェイクしてる(たぶん)のでそのサーバーがlisteningをやめようが別のサーバーがlisteningし始めようが関係ない…!

のでlisteningしてるサーバーがいるかどうかだけで判断すれば良い、みたいな感じかなと!!

wappon28dev added a commit to wappon28dev/voicevox that referenced this issue Jun 2, 2023
wappon28dev added a commit to wappon28dev/voicevox that referenced this issue Jun 2, 2023
@wappon28dev
Copy link
Contributor Author

wappon28dev commented Jun 2, 2023

Re: #1326 (comment), #1326 (comment)

@sabonerune さん, @Hiroshiba さん, なるほど了解です!!! ありがとうございます.
PR #1317 にて, 割り当て可能な判定を LISTENING 以外のみにしました!
(コミットメッセージ間違えちゃったので force push しました… 🤦‍♀️)

(上の activity に書いてあるように, #1317 がマージされたら, この Issue は自動的に close される予定です.)

@Hiroshiba
Copy link
Member

なぜか自動closeされなかったので閉じます! 
ありがとうございました!!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants