MagicStack / MagicStack/asyncpg

Concurrent queries on single connection

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

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

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

説明

  • asyncpg version: 0.22.0
  • PostgreSQL version: 13.2
  • Do you use a PostgreSQL SaaS? If so, which? Can you reproduce
    the issue with a local PostgreSQL install?
    : local PostgreSQL install
  • Python version: 3.9
  • Platform: centos
  • Do you use pgbouncer?: No
  • Did you install asyncpg with pip?: Yes
  • If you built asyncpg locally, which version of Cython did you use?:
  • Can the issue be reproduced under both asyncio and
    uvloop?
    : uvloop
from asyncpg.exceptions import InterfaceError


class CursorIterator:
    def __init__(self, connection, prefetch, portal_name):
        if prefetch <= 0:
            raise InterfaceError("prefetch argument must be greater than zero")

        self._connection = connection
        self._prefetch = prefetch
        self._portal_name = portal_name
        self.rows = []

    def __aiter__(self):
        return self

    async def __anext__(self):
        if not self.rows:
            self.rows = await self._connection.fetch(
                f"FETCH {self._prefetch} FROM {self._portal_name}"
            )

        if self.rows:
            return self.rows.pop(0)

        raise StopAsyncIteration


class Cursor:
    def __init__(self, connection, query, *args, prefetch=None):
        self._connection = connection
        self._args = args
        self._prefetch = prefetch
        self._query = query
        self._portal_name = connection._get_unique_id("portal")

    async def __aenter__(self):
        await self._connection.execute(
            f"DECLARE {self._portal_name} NO SCROLL CURSOR WITH HOLD FOR {self._query}",
            *self._args,
        )

        prefetch = 50 if self._prefetch is None else self._prefetch
        return CursorIterator(self._connection, prefetch, self._portal_name)

    async def __aexit__(self, *args):
        await self._connection.execute(f"CLOSE {self._portal_name}")

Several queries are run concurrently and I receive the following error. What can I do to fix the problem ?

File "asyncpg/protocol/protocol.pyx", line 321, in query
  File "asyncpg/protocol/protocol.pyx", line 684, in asyncpg.protocol.protocol.BaseProtocol._check_state
asyncpg.exceptions._base.InterfaceError: cannot perform operation: another operation is in progress

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

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

はじめの一歩

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

調査の方向性

まず asyncpg/protocol/protocol.pyx の BaseProtocol._check_state 付近を読み、提供されている Cursor と concurrent-query の例と比較します。同じ接続が同時に使用されているかを確認し、期待される動作またはドキュメントの対象範囲を判断します。done の条件は、再現を確認し、maintainer の方針について合意できていることです。

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

評価

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

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

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