MagicStack / MagicStack/asyncpg

asyncpg __del__ methods call asyncio APIs directly, which isn't guaranteed to work and indeed, doesn't work

オープン
#376 コメント 1 件 リアクション 0 件 担当者 0 名 GitHub で見る

まだ誰も着手していません。

主要言語
Python
スター
8.1k
フォーク
468
PR マージ指標
30日以内にマージされた PR はありません

説明

asyncpg has several `__del__` methods that call into asyncio APIs. But... you can't safely call into asyncio APIs from a `__del__` method, because `__del__` methods can be run in arbitrary threads, or at arbitrary moments when the loop's internal data structures are in an inconsistent state.

Discovered here: https://github.com/python-trio/trio-asyncio/issues/44

Looking at the traceback in that issue, I suspect that the reason this hasn't been noticed before is that the `__del__` method ultimately ends up calling `loop.call_soon(...)`. And if you do that from another thread, then with regular asyncio, things will mostly seem to work – it won't actually wake up the loop the way `call_soon_threadsafe` would, but if the loop is still running then it will eventually get run, and the default `call_soon` will not explode or otherwise notice if it's called from the wrong thread. But in that issue, someone's using asyncpg with an alternative asyncio loop that fails when `call_soon` is called from the wrong thread, and this breaks asyncpg.

I guess asyncpg should go through all its `__del__` methods and wrap them in a `loop.call_soon_threadsafe`?

コントリビューションガイド

このリポジトリのコントリビューションガイドは索引されていません

はじめの一歩

  1. issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
  2. 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
  3. リポジトリをフォークし、ブランチを切って変更します。
  4. issue 番号を参照したプルリクエストを送ります。

調査の方向性

まず、asyncpg の __del__ メソッドと、リンクされた Trio issue に関係する loop.call_soon の経路を一覧化します。各クリーンアップ経路について、そこで説明されているスレッドセーフ性と loop の状態に関する懸念を確認します。影響を受けるクリーンアップ動作が、unsafe な直接呼び出しなしで代替の asyncio loop 実装と動作すれば完了です。

索引モデルが issue の本文から書いたものです。

評価

技術スタック
postgresql, python
領域
databases
issue の種類
バグ
難易度
4/5
見積もり時間
3〜5日
活発さ
停滞
明瞭さ
おおむね明確
初心者へのやさしさ
35/100

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。