noteのタイトル画像

[Puppeteer] bitmexのwebsocketが切断されまくって困りました。→何とかしました。

こんばんは。
Puppeteerを使ったbotを何種類か回しています。
puppeteer初の本格実践投入型bot「ヘカトンケイル」は何度もの調整のおかげで順調です。

直近の実績は

みたいな感じです。
上のグラフは本番環境のbitmexでの実際の資産推移です。(いくつも平行して動かしているので、1つのbot環境に割り当て可能な資産が少ないのが欠点ですが)

ちなみに、testnetでの推移は以下です。

testnetなので潤沢に資金を投入しています(笑)
testnetでロジックを磨き、無駄を削ぎ落としてrealnet(本番環境)で調整するというループを使うことでバカみたいなバグで悩まされることは減りました。
私のプログラミングの癖で、非常に多くのオプションを用意して色々な設定での動作を可能にしているのですが、そのためにテストケース数が爆発します。
結構な数のテストをしたと思っていても「あれれ?」っていうバグはやっぱりあります。
よって、testnetはrealnet(本番環境)とは異なった値動きをするのは当たり前ですが、それでも一定の利用価値はありました。

ただ、bitmex側からの突然のwebsocket切断には最後まで悩まされました。
こればかりはこちらのロジックをいくら強化していっても「切断されないようにする」ことが出来ないからです。

最初にトライした対応策は

切断されたら再接続する

というものです。
「いや。。それ当然だし」
って思いますよね。
でも、これがなかなか機能しなかったのです。
正しくは「確実に機能」しなかったのです。

最初のミスは本当に初歩的なミスで、

websocket切断を通知されたスレッド(処理を平行で動かすためにwebsocketの受信処理は別スレッドで動作させていました)から、自分自身のスレッドを再起動させようとした

です。
タコが自分の足を食うとか、自分が家の中にいるのに、家の外から鍵をかけようとしたとか、、そんな感じ(意味が通じませんね)です。

エラーを吐き続けるbotに首を傾げつつ、3時間くらい悩みましたw
理由がわかった時には自分の馬鹿さ加減に驚いたものです。

原因がわかったので処理を見直して実戦投入。
で、、翌朝また停止してました。

理由は

再接続した後にすぐに切断される可能性や、確実に接続されるという保証はない

という、これも初歩的なミスでした。

しかし、いつのタイミングで切断されるかはbitmex側の都合です。
こちらがコントロールすることは出来ません。

よって、やはり第三者(この場合はwebsocketでデータを受信しているスレッドとは別のスレッド)でwebsocketの挙動を監視するしかありません。

我々ソフトウェアエンジニアはこのような処理のことを「watchdog」と呼んだり、相手の鼓動を確認するような動きをすることからハートビート(heartbeat)と呼びます。

websocketのデータ受信が「何らかの理由」で停止したら、その鼓動(データ受信)を監視していた第三者(heartbeat監視)がwebsocketを「外側」から再起動させる

で「強引」に切断を回避しました。

おかげで、ヘカトンケイルも、次期実戦配備予定bot「バーサーカー」も、いまのところ無停止で動いています。

これらのbotのベースになっている「Puppeteer(傀儡師)」は

から取得できます。

楽しいbotライフを!



ソフトウェア・エンジニアを40年以上やってます。 「Botを作りたいけど敷居が高い」と思われている方にも「わかる」「できる」を感じてもらえるように頑張ります。 よろしくお願い致します。