O runtime: o mapa
Item por item da parte 12 da referência Deep Tech — scheduler assíncrono, green threads e event loop — cruzado com o que o DataForge tem.
A décima segunda parte de uma referência Deep Tech é sobre a arquitetura do runtime. Foi a parte que escolhi fazer depois da 8 por um motivo: das que restavam, era a única que muda o que a linguagem consegue fazer, e não só o que ela documenta.
55 · Scheduler assíncrono#
| Item | No DataForge | Onde |
|---|---|---|
| event loop | Arcane.Laco — poller do sistema, fila de prazos, fila de prontas | O laço |
| task scheduler, work queues | agendar, apos, a_cada, com ordem FIFO e prazos num heap | Escalonador |
| executors | L.executar — o que bloqueia vai para um pool e volta pela fila | Escalonador |
| cooperative scheduling | as fibras: cada emit devolve o controle | Fibras |
| context switching | o quadro do gerador; sem pilha própria e sem registrador a salvar | Fibras |
| cancellation | L.cancelar vale para tarefa e para fibra; fechar o gerador roda os defer | Fibras |
| backpressure | L.novo(teto) — a fila recusa em vez de crescer sem limite | Escalonador |
| task stealing | não existe: cada laço é uma thread, e com o GIL o ganho some antes de aparecer | — |
56 · Green threads#
| Item | No DataForge | Onde |
|---|---|---|
| fibers | existem, e são reais: um stream action dirigido pelo escalonador | Fibras |
| user-space scheduling | o escalonador é o do módulo; o SO não sabe que há fibras | Fibras |
| context switching | next() no gerador — o mais barato que há sem sair do Python | Fibras |
| scheduler integration | a fibra diz o que espera, e o laço a registra no poller ou no heap | Fibras |
| stack management, register preservation | não existe, e é a diferença entre fibra e green thread: a corrotina é sem pilha, e um emit dentro de uma ação chamada não suspende | Fibras |
| assembly-level switching | não se aplica — exigiria assembly ou extensão em C, e a linguagem não tem dependência externa | — |
57 · Event loop#
| Componente | No DataForge | Onde |
|---|---|---|
| I/O Poller | selectors.DefaultSelector — o melhor que o sistema oferece | O laço |
| Timer Queue | heap de prazos, com desempate estável | Escalonador |
| Task Queue | fila FIFO com teto opcional | Escalonador |
| Executor | pool de threads para o que bloqueia | Escalonador |
| Reactor, Scheduler | são o mesmo objeto: Laco | O laço |
| epoll | no Linux, automaticamente | O laço |
| kqueue | no macOS e no BSD, automaticamente | O laço |
| IOCP | não: no Windows o selectors usa select, com teto de 512 descritores. É o limite desta forma, e está dito em vez de escondido | — |
| io_uring | não existe: só Linux, e pelo CPython exigiria extensão em C | — |
O resumo honesto#
Das três seções, duas estão inteiras (§55 e §57, menos work stealing, IOCP e io_uring) e a terceira está pela metade — pela metade certa: as fibras existem e funcionam, e o que falta delas (pilha própria) é exatamente o que exigiria sair do Python.