質問: 現在Goを勉強中で,Go+WebSocketを用いて 大人数によるリアルタイムチャットを実装しようとしています. `https://github.com/oreilly-japan/go-programming-blueprints/tree/master/chapter1/chat` を参考に, 「roomの`run()`をgoroutineで動かし,そのroom内でWebSocketで接続するuserを管理する」 と言うようなほぼ同じ実装を行っており, 順調にリアルタイムチャットが動作していることが確認できましたが, 一定上のuser数を超えると,挙動がすこし変わってきました. 観測できた現象としては, roomを動かしているgoroutineは1つ, つまり,チャット部屋は1つしかない,と思っていましたが かなりのユーザを参加させると,ユーザによって参加(接続)しているチャット部屋が違うように観測できました. たとえば,ユーザが200人参加(接続)しているとして, 150人は部屋A,50人は部屋Bに接続されているように見えました. ここから考えられた仮説として, 外部からは1つの部屋(goroutine)に見えるが,**Goが内部的にgoroutineの複製を行って処理を分散させる**. しかし,WebSocketがコネクションを張り続ける性質上,内部的に複製されたgoroutineの1つに接続しつづけるので, ユーザによって外部から入る部屋(goroutine)は同じように見えても,実際に参加(接続)した内部的な部屋は異なるので, 挙動が異なるのではないか,と考えられました. ステートレスなgoroutineであれば,Goが内部的に処理を分散させるのは理にかなっていますが, 長期的なコネクションを持つという,今回のパターンではそれが裏目に出た結果, このような挙動になったのではないかと思いました. 私の知識不足なことがあるのでしょうが,Goの仕様として WebSocketの接続数や何らかの負荷が原因で 全く同じgoroutineが「勝手に」複製される, というようなことはあるのでしょうか? また,それがあるとすれば その複製をさせずに,全ユーザを同じroomに参加させるにはどうすればいいでしょうか? よろしくお願いいたします.
回答: 全く同じgoroutineが「勝手に」複製されるということはありえません。 例えばプロセスを止めきらずにもう一つプロセスを起動できたりすると 分断した部屋が存在する可能性があるかもしれません。