Skip to content

Feature/linux epoll provider#142

Merged
cesarliws merged 41 commits into
cesarliws:mainfrom
regyssilveira:feature/linux-epoll-provider
Jun 26, 2026
Merged

Feature/linux epoll provider#142
cesarliws merged 41 commits into
cesarliws:mainfrom
regyssilveira:feature/linux-epoll-provider

Conversation

@regyssilveira

Copy link
Copy Markdown
Contributor

🚀 PR: Provedor Linux Epoll de Ultra-Performance para o Dext

📝 Descrição

Este PR introduz o novo provedor de servidor nativo para Linux baseado na API de sinalização de eventos Epoll do kernel Linux. A implementação foi focada em obter vazão máxima com latência ultra-baixa, adotando conceitos de Zero-Object e Zero-Allocation na camada crítica de parsing HTTP e despacho vetorizado de IO.

🛠️ Principais Mudanças e Arquitetura

1. Zero-Object & Zero-Allocation Parser (Dext.Server.Epoll.pas)

  • Mapeamento Sem Alocação: Criamos o registro THeaderSegment para indexar a posição e limites (Start, Length) de cada chave e valor de cabeçalho diretamente sobre o buffer bruto de bytes da requisição.
  • Eliminação de Coleções da Heap: Substituímos o dicionário (TDictionary) no loop do parser por um array dinâmico nativo de registros (TArray<THeaderSegment>). O parser agora não aloca nenhuma instância de classe a cada request.
  • Busca e Parsing Sem Strings: A localização de headers é feita via varredura linear cache-friendly e comparação de bytes bruta (CompareBytesCI). A decodificação de cabeçalhos de controle (como Content-Length) foi reescrita para fazer a conversão numérica caractere por caractere diretamente dos bytes, sem alocar strings intermediárias.

2. Escrita Vetorizada com Chamada de Sistema writev

  • Redesenhamos a resposta HTTP (TDextEpollResponse) para acumular os buffers de cabeçalho e corpo da resposta.
  • O envio final é despachado por meio da syscall vetorizada writev do Linux utilizando uma estrutura iovec, reduzindo o número de chamadas de sistema na rede de duas para uma por requisição.

3. Reactor Desacoplado Concorrente

  • O processamento das requisições e a execução dos pipelines HTTP do Dext foram movidos do laço principal do Epoll (epoll_wait) para threads trabalhadoras via TTask.Run.
  • Implementamos isolamento por request (ProcessRequestAsync) para garantir que dados de conexão concorrentes não sofram race conditions e que os recursos do socket sejam limpos de forma thread-safe.

📊 Resultados do Benchmark Real (Linux Ubuntu / Docker)

O ambiente foi validado por meio de testes de carga simulando concorrência intensa de 200 conexões paralelas utilizando a ferramenta wrk (4 threads por 15 segundos):

Métrica Dext Epoll (Pós-Otimização) Horse Epoll (Referência) Fator de Ganho
Vazão (Throughput) 15.286,58 RPS 6.169,66 RPS + 147,7% (2.47x mais veloz)
Latência Média 11,80 ms 41,05 ms - 71,2% (3.47x menor)
Latência Máxima (Pico) 176,13 ms 1.730,00 ms 89,8% menos atraso
Respostas de Erro (HTTP != 2xx) 0 52.869 0% de falha vs 57,1% no Horse
Timeouts 0 31 Estabilidade absoluta

Conclusão dos Testes

  • O Dext Epoll processou todas as 230.284 requisições com 0% de erro de protocolo.
  • Sob a mesma carga, o concorrente de referência apresentou quedas e gargalos de enfileiramento, resultando em falhas em mais de metade (57,1%) de suas requisições.

🧪 Como Testar Localmente

Para testes manuais:

  1. Compile a aplicação no Delphi 12 para a plataforma Linux64.
  2. Execute o binário em seu ambiente Docker/WSL2 utilizando a flag nativa:
    ./SeuApp --server -httpsys (no Linux, a engine nativa redireciona automaticamente para o provedor Epoll).
  3. Dispare testes de carga usando wrk ou autocannon para validar a vazão e a estabilidade.

@cesarliws cesarliws merged commit 7135e1d into cesarliws:main Jun 26, 2026
@regyssilveira regyssilveira deleted the feature/linux-epoll-provider branch June 26, 2026 18:39
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants