質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.77%

  • Go

    457questions

    Go(golang)は、Googleで開発されたオープンソースのプログラミング言語です。

  • WebSocket

    166questions

    WebSocketとは双方向・全二重コミュニケーションのためのAPIでありプロトコルのことを指します。WebSocketはHTML5に密接に結びついており、多くのウェブブラウザの最新版に導入されています。

【Golang, Go言語】goroutineの疑似プロセス複製?

解決済

回答 1

投稿

  • 評価
  • クリップ 1
  • VIEW 342

akachachi

score 30

現在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に参加させるにはどうすればいいでしょうか?

よろしくお願いいたします.

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • akachachi

    2017/11/09 16:11

    オリジナルのソースでの検証は行っていません.チャット部屋の作成やユーザの入退出といった部分は同じですので,オリジナルサーバでも同様のことが発生すると思いますが,なにぶんブラックボックス化されている部分だと思いますのでこの挙動を安定して再現する方法もわかりません.

    キャンセル

  • KSwordOfHaste

    2017/11/09 16:29

    質問者さんの推測通りとすると(確信はないですが)goのバグのように思えてきます。なお自分はWin10でhttps://github.com/golang/goからinstallしたものを使ってますが、NumCPU,GOMAXPROCSともに4(2coreのPCです)でした。もしご質問の現象の再現性があるならGOMAXPROCSを1に制限して再現するか確認してみると閲覧者にとっても参考になる気がします。

    キャンセル

  • mattn

    2017/11/12 23:21

    ソールが無いので断言は出来ませんが、ukai さんのサンプルは部屋が1つでクッキー等も使っていないので現在ブラウザが開いている部屋がどちらなのかを判定するコードもありません。おそらくですが、その現象が発生したユーザはA/B両方の端末に接続されたのではないでしょうか?同じ websocket を A/B 双方にリクエストしてしまい、それぞれの map に同じコネクションが含まれてしまったのでは?という推測は出来ます。

    キャンセル

回答 1

checkベストアンサー

+1

全く同じgoroutineが「勝手に」複製されるということはありえません。
例えばプロセスを止めきらずにもう一つプロセスを起動できたりすると
分断した部屋が存在する可能性があるかもしれません。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 90.77%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

  • 解決済

    WebSocketとAjaxの違いについて

    最近HTML5関連の話題でWebSocketやWebRTC、WebGLという言葉を良く聞きますが、WebSocketについてはAJaxでも十分な気がしています。 サンプルコードで

  • 受付中

    Websocket と enchant.js を利用した画面の書換え

    WebSocketからJSONをうけとって、そのJSONを元に画面を書き換えるプログラムです。 // グローバル変数の定義 var connection = new WebSoc

  • 受付中

    websocket実装方法

    websocketを使ってチャットを作成したいです。 IDEはNetBeansを使用しています。 実装方法を詳しく教えてください。

  • 解決済

    WebSocketの使い道

    WebSocketを利用した、或いは利用したい、という方の使い道を教えてください。勿論、差し障りの無い範囲で構いません。 また、どの言語で、どのようにしてWebSocketの仕組み

  • 解決済

    centOS7にてsocket.ioのインストールがうまくいかない

    websocketを利用してみたいと考え、npmを用いてsocket.ioをインストールしようとしたところ、下記のようなエラーが表示されインストールがうまくいきません。 どのように

  • 受付中

    Rails5 Action Cableでチャットをチャットルームに紐付けしたい

    Rails5でAction Cableを使って http://qiita.com/jnchito/items/aec75fab42804287d71b こちらの記事を参考に、リ

  • 受付中

    websocket(socket.io)のroomの管理方法について

    javascriptでのwebsocket実装を試みているのですが、 1.存在するroomの一覧 2.roomに何人いるか をsocket.ioモジュールの機能で取得する

  • 受付中

    rails actioncableについて

    疑問 Action cableでRails リアルタイムにApi取得が可能か 理由 Action Cableでリアルタイムにチャット更新という例がありますがあれは、DBが変化し

同じタグがついた質問を見る

  • Go

    457questions

    Go(golang)は、Googleで開発されたオープンソースのプログラミング言語です。

  • WebSocket

    166questions

    WebSocketとは双方向・全二重コミュニケーションのためのAPIでありプロトコルのことを指します。WebSocketはHTML5に密接に結びついており、多くのウェブブラウザの最新版に導入されています。