Feature/horse core optimization - #507
Merged
regyssilveira merged 13 commits intoJul 8, 2026
Merged
Conversation
…aded, avoiding heap allocations on static routes
… avoiding heap allocation on stateless API requests
… Res.Abort and Res.Aborted check in middlewares pipeline
…-loaded recycled memory allocator in THorseRequest
…, and Epoll providers to bypass string-to-utf8 encoding when raw bytes are passed
… and configure socket keep-alive values in Indy-based providers
…st and Horse.Response; merge Arena changes directly into Horse.Commons
…TBytes) shadow array, and THorseRequest.Arena object lifecycle registration
… (OPTIONS) and Authentication (Auth) middleware flows
…d Johnson middleware
…zarus integration server
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Pull Request: Otimizações de Alta Performance e Ciclo de Vida do Core do Horse & Provedor Indy (Fase 1)
📌 Descrição Geral
Este Pull Request implementa otimizações planejadas para o core do framework Horse e seu provedor padrão Indy. As modificações focam em reduzir a latência de tráfego, o overhead de alocação de memória (heap) sob alta concorrência e locks de thread do SO.
Toda a suíte de 24 variantes de testes unitários multiversão (do Delphi 10 Seattle ao Delphi 13 Florence) foi validada, e três novos testes unitários específicos foram desenvolvidos para garantir a cobertura contínua dessas novas APIs públicas.
🛠️ O que foi feito de novo?
1. Lazy-Loading no Core (
THorseRequest)FSessions: THorseSessions) agora é instanciada em modo lazy-loading. Em APIs clássicas REST stateless (onde sessões não são usadas), o overhead de criação e destruição do dicionário de sessões no heap é reduzido a zero.2. Parâmetros Otimizados no Roteador Radix
LParamsseja criada somente quando um parâmetro de rota dinâmica (como:ou*) for de fato detectado. Rotas estáticas como/ping,/api/healthou/v1/statusagora rodam com zero alocações no heap.3. Mecanismo de Curto-Circuito sem Exceções (
Res.Abort)raise).FAborted, a propriedadeAbortede o método.AbortemTHorseResponse. Ganchos nos despachantes do pipeline (TRadixFlow.NexteTNextCaller.Next) verificam a flag e interrompem a execução de forma limpa. A compatibilidade com exceções clássicas (EHorseException) foi 100% mantida.4. Arena Allocator Reciclada e Pooled (
Horse.Commons)THorseArenaAllocatororiginal emsrc/Horse.Commons.pasinjetando controle de ciclo de vida seguro de objetos complexos comRegisterObject(AObject). Ao final de cada requisição do pool, a chamada a.Clearzera os ponteiros do buffer de memória contíguo e libera de forma atômica todos os objetos registrados, sem desalocar a memória física da RAM, reduzindo a fragmentação no FastMM4.5. Escrita Direta de Bytes (
Res.Send(TBytes)) e Zero-CopyRes.Send(const AContent: TBytes)e a propriedade de sombraBodyBytesemTHorseResponse. Provedores de rede (Indy, IOCP, HTTP.sys e Epoll) foram otimizados para despachar diretamente esses bytes no soquete, evitando alocações e conversões de strings UTF-16 temporárias na CPU.6. Otimizações de Socket & Thread Pool no Provedor Indy (Default)
TIdSchedulerOfThreadPoolpara reutilizar as threads ativas do sistema operacional noTIdHTTPServer, eliminando a criação e destruição excessiva de threads por conexão.UseNagle := False) para mitigar atrasos de buffer artificial de 200ms em pacotes pequenos e configuração de Keep-Alive nativo de transporte TCP.🧪 Cobertura de Testes Unitários (Novos Testes)
Adicionamos cobertura explícita de testes unitários baseados no framework DUnitX:
TTestHorseCoreMiddleware.TestMiddlewareExceptionFreeAbortemtests/src/tests/Tests.Horse.Core.Middleware.pas:Res.Abortimpede a execução das rotas e middlewares subsequentes, mantendo o status HTTP configurado e a flag de abortamento ativa, sem disparar exceções na pilha.TTestHorseRequestRecycle.TestRequestArenaRecyclingAndObjectLifetimeemtests/src/tests/Tests.Horse.Request.Recycle.pas:.Clearda requisição.TTestHorseRequestRecycle.TestResponseSendBytesOverloademtests/src/tests/Tests.Horse.Request.Recycle.pas:Send(TBytes)popula corretamente o arrayBodyBytesna resposta HTTP.📈 Matriz de Testes Multiversão (24/24 Passou Verde)
THorseArenaAllocatorfoi estendida sem alterar suas propriedades originais (Buffer,Start,Len), garantindo a preservação total das árvores de rotas que já a utilizavam.