Hacktoberfest 2026 : les issues que les mainteneurs ont marquées pour octobre, ouvertes et accessibles aux débutants. Parcourir les issues Hacktoberfest

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

Ouverte
#1,939 3 commentaires 0 réactions 0 personnes assignées Voir sur GitHub

Personne n'a encore pris cette issue.

Évaluation

Difficulté
4/5
Temps estimé
3-5 jours
Accessibilité débutants
52/100
Type d'issue
Bug
Clarté
Plutôt claire
Activité
Calme
Stack technique
python
Domaine
networking

Piste de recherche

Commencez par can/notifier.py aux lignes référencées de _rx_thread() et suivez _on_message_received() ainsi que le chemin de planification de asyncio. Examinez les issues #1938 et #1912 en parallèle de cette modification. Le travail est terminé lorsque les callbacks non async peuvent rester sur le thread de réception CAN lorsqu’ils sont configurés ainsi, tandis que les callbacks async sont planifiés de manière sûre depuis l’un ou l’autre thread, sans modifier le comportement par défaut.

Rédigé par le modèle d'indexation à partir du texte de l'issue.

Description

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.

Langage dominant
Python
Étoiles
1.6k
Forks
697
Métriques de merge des PR
Aucune PR mergée en 30 j

Guide de contribution

Ouvrir le guide de contribution

Par où commencer

  1. Lisez l'issue en entier, puis le guide de contribution du projet.
  2. Signalez en commentaire que vous la prenez — cela évite que deux personnes fassent le même travail.
  3. Forkez le dépôt et travaillez sur une branche.
  4. Ouvrez une pull request qui référence le numéro de l'issue.

Autres issues de hardbyte/python-can

Toutes les issues de hardbyte/python-can

Issues similaires

Plus d'issues Python

Recevez les nouvelles issues par e-mail

Un résumé court des issues GitHub adaptées aux débutants.