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

bot ロジックにおける WebSocket の接続性について #176

Open
MtkN1 opened this issue Jul 22, 2022 · 1 comment
Open

bot ロジックにおける WebSocket の接続性について #176

MtkN1 opened this issue Jul 22, 2022 · 1 comment
Assignees

Comments

@MtkN1
Copy link
Member

MtkN1 commented Jul 22, 2022

WebSocket が「TCP コネクションが繋がっているが、メッセージが受信されない」状態の時、 bot が無限待機されたりロジックにバグが発生する可能性がある。

課題

以下は FTX - WebSocket API - Ticker の接続イベントとメッセージのログである。
このログは WebSocket が何かの要因で切断され、その後再接続されていることを表している。

...
2022-07-21 16:35:04.044 | DEBUG    | __main__:main:65 - {"channel":"ticker","market":"BTC-PERP","type":"update","data":{"bid":23048.0,"ask":23049.0,"bidSize":1.6196,"askSize":9.6219,"last":23048.0,"time":1658421303.9519827}}
2022-07-21 16:35:04.065 | DEBUG    | __main__:main:65 - {"channel":"ticker","market":"BTC-PERP","type":"update","data":{"bid":23048.0,"ask":23049.0,"bidSize":1.6196,"askSize":10.1961,"last":23048.0,"time":1658421303.98429}}
2022-07-21 16:35:10.577 | DEBUG    | __main__:main:67 - closing
2022-07-21 16:35:10.578 | DEBUG    | __main__:main:70 - closed
2022-07-21 16:35:10.578 | DEBUG    | __main__:main:53 - connecting
2022-07-21 16:35:11.179 | DEBUG    | __main__:main:61 - open
2022-07-21 16:35:11.351 | DEBUG    | __main__:main:65 - {"type":"subscribed","channel":"ticker","market":"BTC-PERP"}
2022-07-21 16:35:11.380 | DEBUG    | __main__:main:65 - {"channel":"ticker","market":"BTC-PERP","type":"update","data":{"bid":23050.0,"ask":23051.0,"bidSize":0.728,"askSize":7.6433,"last":23050.0,"time":1658421311.290771}}
2022-07-21 16:35:11.395 | DEBUG    | __main__:main:65 - {"channel":"ticker","market":"BTC-PERP","type":"update","data":{"bid":23050.0,"ask":23051.0,"bidSize":0.709,"askSize":7.6433,"last":23050.0,"time":1658421311.3138447}}

注目する必要があるのが 2022-07-21 16:35:04.065 の最後のメッセージから 2022-07-21 16:35:10.578 の closed までの時間、約6秒の間がある。
つまり、この期間は「ws.closed == False だが、メッセージが受信されない」ことになる。

pybotters の DataStore のような WebSocket のデータを頻繁に参照する bot においては、リクエストした REST API のレスポンスと同等のデータが DataStore に反映されるまで watch メソッドで待つと言ったユースケースが存在する。
そのユースケースの際、watch メソッドが無限待機にならないように if not ws.closed: と確認してから watch メソッドに入ったとしても、上記メッセージが受信されない期間に当たってしまうと無限待機になってしまう。

対策

  1. watch メソッドにタイムアウトを設定可能にする
    Pros: 簡単な実装でタイムアウトさせて無限待機を回避できる
    Cons: 正しくないタイムアウトが発生する場合がある

  2. WebSocket open 時のコールバックに store.initialize を設定できるようにする
    Pros: REST API によるデータから無限待機を回避できる
    Cons: REST API によるデータで必ず watch メソッドがイテレーションするとは限らない(そもそも、この件に限らず open 時に initialize するべき)

  3. WebSocket が切断されたら bot ロジックも終了させる.
    Pros: 最も堅牢な方法でロジックにバグが起こりにくい
    Cons: pybotters の WebSocket クラスを自動再接続されないものに変更する必要があり、書き方も大きく変わる

  4. watch メソッドに WebSocket closed な例外を伝搬させる
    Pros: 従来の書き方を大きく変更せず無限待機を対処でき、タイムアウトより正確
    Cons: DataStore を WebSocket の概念に依存させる必要がある

@MtkN1 MtkN1 self-assigned this Jul 22, 2022
@MtkN1
Copy link
Member Author

MtkN1 commented Feb 6, 2024

これを解決する API を提供するには、構造化並行処理 (structured concurrency) のパラダイムに従う必要がありそう 🤔

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

No branches or pull requests

1 participant