MagicStack / MagicStack/uvloop

inconsistent file descriptor blocking state when running in asyncio vs uvloop

Ouverte
#712 0 commentaires 0 réactions 0 personnes assignées Voir sur GitHub

Personne n'a encore pris cette issue.

Langage dominant
Cython
Étoiles
11.9k
Forks
615
Métriques de merge des PR
Aucune PR mergée en 30 j

Description

When running under uvloop, registering stdin, stdout, or stderr with loop.add_reader() / loop.add_writer() implicitly changes their blocking mode from blocking to non-blocking. This behaviour does not occur under the standard asyncio selector event loop.

This is causing some issues when running with rich/promptkit in fast-agent

Under the following test code

import anyio
import sys
import os
import asyncio

async def main():

    loop = asyncio.get_running_loop()
    print(f"Using event loop: {type(loop)}")

    stdin = sys.stdin.fileno()
    stdout = sys.stdout.fileno()
    stderr = sys.stderr.fileno()

    print(f"initial:\tstdin fd: {stdin}, stdout fd: {stdout}, stderr fd: {stderr}")
    print(f"blocking:\tstdin fd: {os.get_blocking(stdin)}, stdout fd: {os.get_blocking(stdout)}, stderr fd: {os.get_blocking(stderr)}")

    loop.add_writer(stdin, lambda: None)
    loop.add_writer(stdout, lambda: None)
    loop.add_writer(stderr, lambda: None)

    print(f"writer: \tstdin fd: {stdin}, stdout fd: {stdout}, stderr fd: {stderr}")
    print(f"blocking:\tstdin fd: {os.get_blocking(stdin)}, stdout fd: {os.get_blocking(stdout)}, stderr fd: {os.get_blocking(stderr)}")

    loop.add_reader(stdin, lambda: None)
    loop.add_reader(stdout, lambda: None)
    loop.add_reader(stderr, lambda: None)

    print(f"reader: \tstdin fd: {stdin}, stdout fd: {stdout}, stderr fd: {stderr}")
    print(f"blocking:\tstdin fd: {os.get_blocking(stdin)}, stdout fd: {os.get_blocking(stdout)}, stderr fd: {os.get_blocking(stderr)}")

anyio.run(main, backend="asyncio", backend_options={"use_uvloop": False})
print("-" * 40)
anyio.run(main, backend="asyncio", backend_options={"use_uvloop": True})

I see the following output, where the blocking status of the stdio file descriptors are changed from blocking to non blocking when running under uvloop but not asyncio.

Using event loop: <class 'asyncio.unix_events._UnixSelectorEventLoop'>
initial:        stdin fd: 0, stdout fd: 1, stderr fd: 2
blocking:       stdin fd: True, stdout fd: True, stderr fd: True
writer:         stdin fd: 0, stdout fd: 1, stderr fd: 2
blocking:       stdin fd: True, stdout fd: True, stderr fd: True
reader:         stdin fd: 0, stdout fd: 1, stderr fd: 2
blocking:       stdin fd: True, stdout fd: True, stderr fd: True
----------------------------------------
Using event loop: <class 'uvloop.Loop'>
initial:        stdin fd: 0, stdout fd: 1, stderr fd: 2
blocking:       stdin fd: True, stdout fd: True, stderr fd: True
writer:         stdin fd: 0, stdout fd: 1, stderr fd: 2
blocking:       stdin fd: False, stdout fd: False, stderr fd: False
reader:         stdin fd: 0, stdout fd: 1, stderr fd: 2
blocking:       stdin fd: False, stdout fd: False, stderr fd: False

Guide de contribution

Aucun guide de contribution indexé pour ce dépôt

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.

Piste de recherche

Commencez par exécuter la reproduction fournie de asyncio par rapport à uvloop et examinez les points d’entrée de uvloop pour loop.add_reader() et loop.add_writer(). Comparez leur gestion des descripteurs de fichier avec celle de la boucle sélecteur standard d’asyncio ; c’est terminé lorsque l’enregistrement de stdin, stdout et stderr préserve leur état bloquant sous uvloop.

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

Évaluation

Stack technique
python
Domaine
operating-systems
Type d'issue
Bug
Difficulté
4/5
Temps estimé
3-5 jours
Activité
À l'abandon
Clarté
Plutôt claire
Accessibilité débutants
38/100

Recevez les nouvelles issues par e-mail

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