Hacktoberfest 2026:メンテナが10月に向けて印を付けた、オープンで初心者向けの issue。 Hacktoberfest の issue を見る

Using async changes thread for non-async callbacks which is unexpected

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

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

評価

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

調査の方向性

参照されている _rx_thread() の行にある can/notifier.py から始め、_on_message_received() と asyncio のスケジューリングパスを追ってください。この変更とあわせて issue #1938 と #1912 を確認してください。完了条件は、設定時に非 async コールバックを CAN 受信スレッド上に残せる一方で、async コールバックをどちらのスレッドからでも安全にスケジュールでき、デフォルトの動作を変更しないことです。

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

説明

bug

Using the can library with async enabled Notifier change the thread which all callbacks is called from. Without async, the notifier callbacks are run in the thread of the can rx thread. With async, it runs the callbacks via loop.call_soon_threadsafe() which cause the notifier callbacks to be run in the main async thread instead. This changes behavior for all callbacks, not just async callbacks, which is unexpected. E.g. if using a non-async can protocol stack plus another async protocol stack together might create problems due to the change of callback threads.

https://github.com/hardbyte/python-can/blob/5d62394006f42d1bf98e159fe9bb08d10e47e6eb/can/notifier.py#L111-L119

I propose a fix that prevents the async call_soon_threadsafe in Notifier._rx_thread() with the introduction of a setting run_message_reception_in_eventloop. Then the user can chose to opt out of running the regular non-async callbacks in the asyncio main thread. The default should be True so we don't change the current behavior.

def _rx_thread(self, bus: BusABC) -> None:
    # determine message handling callable early, not inside while loop
    if self._loop and self.run_message_reception_in_eventloop:              # <--- NEW
        handle_message: Callable[[Message], Any] = functools.partial(
            self._loop.call_soon_threadsafe,
            self._on_message_received,  # type: ignore[arg-type]
        )
    else:
        handle_message = self._on_message_received

A change is required in Notifier._on_message_received(). This function might be called in either threads, so calling the asyncio coroutine must be made thread safe:

def _on_message_received(self, msg: Message) -> None:
    for callback in self.listeners:
        res = callback(msg)
        if res and self._loop and asyncio.iscoroutine(res):
            # Schedule coroutine
            # In __init__: self._tasks: set[asyncio.Task] = set()
            task = asyncio.run_coroutine_threadsafe(res, self._loop)

When looking at this, #1938 and #1912 should be addressed in the same round.

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

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

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

はじめの一歩

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

hardbyte/python-can のほかの issue

hardbyte/python-can の issue をすべて見る

似ている issue

Python の issue をもっと見る

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

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