MagicStack / MagicStack/uvloop

inconsistent file descriptor blocking state when running in asyncio vs uvloop

Aberta
#712 0 comentários 0 reações 0 responsáveis Ver no GitHub

Ninguém assumiu esta issue ainda.

Linguagem predominante
Cython
Estrelas
11.9k
Forks
616
Métricas de merge de PRs
Nenhum PR com merge em 30d

Descrição

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](https://github.com/evalstate/fast-agent)

Under the following test code

```python
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:
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:
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
```

Guia de contribuição

Nenhum guia de contribuição indexado para este repositório

Primeiros passos

  1. Leia a issue inteira e depois o guia de contribuição do projeto.
  2. Comente na issue dizendo que vai assumir — evita que duas pessoas façam o mesmo trabalho.
  3. Faça um fork do repositório e trabalhe em uma branch.
  4. Abra um pull request que referencie o número da issue.

Direção de pesquisa

Comece executando a reprodução fornecida de asyncio em comparação com uvloop e inspecione os pontos de entrada de uvloop para loop.add_reader() e loop.add_writer(). Compare o tratamento de descritores de arquivo deles com o loop de seletor padrão do asyncio; considera-se concluído quando registrar stdin, stdout e stderr preserva o estado de bloqueio deles no uvloop.

Escrita pelo modelo de indexação a partir do texto da issue.

Avaliação

Stack de tecnologia
python
Domínio
operating-systems
Tipo de issue
Bug
Dificuldade
4/5
Tempo estimado
3-5 dias
Status de atividade
Estagnada
Clareza
Razoavelmente clara
Facilidade para iniciantes
38/100

Receba novas issues na sua caixa de entrada

Um resumo curto de issues do GitHub para quem está começando.