Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Racional de Design Assíncrono para SDKs

Resumo Executivo

Cada SDK implementa padrões assíncronos otimizados para seu ecossistema:

SDKPadrãoRacional
TypeScriptAsync/await realPromises nativas do JS, padrão web
PythonBloqueante + padrões asyncioEvita conflitos de versão do PyO3, soluções documentadas
SwiftBloqueante + wrapper TaskAlinha com a Concorrência do Swift, simples e comprovado

Todos os três alcançam I/O não bloqueante em seus respectivos ecossistemas através de meios idiomáticos da linguagem.


TypeScript: ✅ Totalmente Assíncrono

Implementação

pub async fn get_status(&self) -> Result<String, JsValue>

Compilado para WASM com wasm-bindgen-futures → Promises JavaScript.

Por que funciona

  1. Promessa Nativa do JavaScript: Todo async no JS retorna Promise<T>
  2. Fronteira WASM: wasm-bindgen lida com a conversão de Promise automaticamente
  3. Sem Conflitos de Versão: wasm-bindgen (0.2) é estável, sem problemas como o PyO3
  4. Leve: Promises são abstrações de custo zero em mecanismos JS modernos

Uso

const status = await client.getStatus(); // Natural, idiomático

Trade-offs

AspectoTrade-off
Eficiência✅ Overhead zero (promise nativa)
Simplicidade✅ Único caminho de implementação
Compatibilidade✅ Todos os navegadores + Node.js

Python: ⏳ Bloqueante + Guia de Integração Async

Implementação

def get_status(&self) -> str:
    return self.rt.block_on(self.client.get_status()).await

Método Python síncrono usando um runtime Tokio oculto.

Por que NÃO Async Real (pyo3-asyncio)

Problema de Conflito de Versão:

pyo3 = 0.21
pyo3-asyncio = 0.20  ← requer pyo3 = 0.20
                        Conflito! ❌

Caminho de Atualização Bloqueado:

  • PyO3 0.21 tem nova API (suporte a corrotinas)
  • pyo3-asyncio 0.20 ainda não atualizou
  • Única solução: fazer o downgrade do PyO3 para 0.20 (perde novos recursos)

Correção Esperada: PyO3 0.22+ (Q3-Q4 2026)

  • pyo3-asyncio atualizará para 0.22
  • Sem mais conflitos de versão
  • Async real possível

Solução Atual: asyncio.to_thread()

Para contextos assíncronos, use o padrão de integração asyncio:

import asyncio
from paebiru import PaebiruClient

client = PaebiruClient("http://...")

async def main():
    # Chamada não bloqueante para função bloqueante
    status = await asyncio.to_thread(client.get_status)

Por que funciona

  1. Seguro para GIL: O pool de threads está ciente do GIL
  2. Não bloqueante: O loop de eventos continua enquanto a thread executa
  3. Padrão: Embutido no Python 3.9+
  4. Sem Dependências: Sem conflitos de versão

Performance

  • Inicialização da thread: ~0.5ms (reutilizada com executor)
  • I/O de rede: 1-5ms (fator dominante)
  • Memória: ~8MB por thread

Trade-offs

AspectoTrade-off
Eficiência⏳ Usa thread do SO (não leve)
Simplicidade⏳ Requer wrapper asyncio.to_thread()
Compatibilidade✅ Python 3.9+ (3.7-3.8 usam executor)
Confiabilidade✅ Sem conflitos de versão

Caminho de Migração

Agora (PyO3 0.21):

# Solução alternativa para async
status = await asyncio.to_thread(client.get_status)

Futuro (PyO3 0.22+):

# Async nativo (planejado)
client_async = AsyncPaebiruClient("http://...")
status = await client_async.get_status()

Swift: Bloqueante + Swift Concurrency

Implementação

func getStatus() throws -> String

Método síncrono usando runtime Tokio oculto.

Por que Bloqueante (Não Swift async nativo)

Racional do Trade-off:

  1. Simplicidade de Implementação

    • Bloqueante: 150 linhas de FFI
    • Async nativo: Requer wrappers async/await personalizados
    • Bridging Tokio ↔ Swift async complexo
  2. Alinha-se com o Modelo de Concorrência do Swift

    • O async/await do Swift envolve operações síncronas
    • O usuário envolve o SDK bloqueante em Task { }:
      Task {
          let status = try await Task.detached(priority: .userInitiated) {
              try node.getStatus()
          }.value
      }
      
  3. Padrão Comprovado

    • Muitas bindings Rust FFI usam isso (especialmente iOS)
    • Familiar para desenvolvedores Swift
    • Baixa fricção para adoção

Integração com Swift Concurrency

Wrapper para Concorrência:

actor PaebiruNodeAsync {
    private let node: PaebiruNode

    init(baseUrl: String) throws {
        self.node = try PaebiruNode(baseUrl: baseUrl)
    }

    nonisolated func getStatus() async throws -> String {
        return try Task.detached(priority: .userInitiated) {
            try node.getStatus()
        }.value
    }
}

Uso

let node = try PaebiruNodeAsync(baseUrl: "http://...")

Task {
    let status = try await node.getStatus()
    print(status)
}

Trade-offs

AspectoTrade-off
Eficiência⏳ Troca de contexto de Task (leve)
Simplicidade✅ SDK simples, wrapper simples
Compatibilidade✅ Swift 5.5+ (todos os iOS/macOS modernos)
Natividade⏳ Não é Swift async nativo (wrapper necessário)

Análise Comparativa

Ranking de Eficiência

  1. TypeScript (✅ Melhor): Promises de custo zero, nativo
  2. Swift (⏳ Bom): Troca de contexto de Task leve
  3. Python (⏳ Aceitável): Overhead de thread do SO, mas aceitável para I/O-bound

Ranking de Simplicidade

  1. Python (✅ Melhor): Chamadas bloqueantes diretas
  2. TypeScript (✅ Bom): Async/await direto
  3. Swift (⏳ Regular): Requer wrapper Task

Ranking de Confiabilidade

  1. Python (✅ Melhor): Sem conflitos de versão, padrões documentados
  2. TypeScript (✅ Melhor): Ecossistema wasm-bindgen estável
  3. Swift (✅ Bom): Sem dependências assíncronas externas

Matriz de Decisão

Ao escolher o padrão assíncrono por linguagem:

CritérioImportante para
Suporte NativoWeb (TS: Promises), Sistema (Swift: concurrency), Runtime (Python: asyncio)
Estabilidade de VersãoBibliotecas (conflitos PyO3), ecossistemas (npm estável, crates.io estável)
UX do DesenvolvedorCurva de aprendizado, boilerplate, fricção de integração
PerformanceI/O-bound (rede), compute-bound, tempo real

Resumo

Todos os três padrões são corretos para seu ecossistema:

  • TS: Usa o que o JavaScript fornece nativamente
  • Python: Usa o modelo assíncrono do Python + contorna conflitos de biblioteca
  • Swift: Usa Swift Concurrency + bridging pragmático

Futuro: Interface Assíncrona Unificada

Quando o PyO3 0.22+ estabilizar (Q3-Q4 2026):

# Async real, sem conflitos
from paebiru import AsyncPaebiruClient

client = AsyncPaebiruClient("http://...")
status = await client.get_status()  # Nativo!

Então todos os três SDKs terão:

  • ✅ Async nativo da linguagem
  • ✅ Zero boilerplate
  • ✅ Performance otimizada

Isso unifica a DX mantendo implementações idiomáticas da linguagem.


Recomendações

Para Código Síncrono

  • Python: Use PaebiruClient diretamente
  • TypeScript: Use await de nível superior (ou Promise.then())
  • Swift: Use PaebiruNode diretamente

Para Código Assíncrono

  • Python: await asyncio.to_thread(client.method)
  • TypeScript: await client.method() (nativo)
  • Swift: Envolva em Task { } ou actor

Para Alta Concorrência

  • Python: asyncio.gather() com executor de thread
  • TypeScript: Promise.all() (natural)
  • Swift: async let ou concorrência estruturada

Para Produção

  • Todos os três padrões estão prontos para produção
  • Recomendado seguir as convenções da linguagem
  • Documentar padrões assíncronos no onboarding do projeto

Referências