Skip to content

Feature/multi instance - #517

Merged
regyssilveira merged 4 commits into
HashLoad:masterfrom
regyssilveira:feature/multi-instance
Jul 10, 2026
Merged

Feature/multi instance#517
regyssilveira merged 4 commits into
HashLoad:masterfrom
regyssilveira:feature/multi-instance

Conversation

@regyssilveira

Copy link
Copy Markdown
Contributor

PR: Estabilização e Documentação da Arquitetura Multi-Instance (Delphi / FPC)

Este Pull Request consolida a estabilização completa da branch feature/multi-instance do framework Horse. Corrigimos todas as incompatibilidades de compilação cruzada com o Free Pascal (FPC 3.2.2 / Lazarus / Linux) e asseguramos 100% de integridade e cobertura na suíte de testes unitários e de integração no Delphi (Windows).

Além disso, foram adicionados exemplos práticos simplificados de console, documentação técnica bilíngue detalhando o comportamento de rede e novos scripts de testes automatizados ponta a ponta (E2E).


🛠️ Alterações e Resolução de Problemas (Bug Fixes)

1. Compatibilidade Cross-Platform (FPC / Lazarus)

  • Operações Atômicas de Thread: Substituímos chamadas diretas a TInterlocked (ausente/incompleto em versões do FPC no Linux) por condicionais de compilação utilizando as APIs nativas da RTL do Free Pascal (InterlockedIncrement e InterlockedDecrement) em src/Horse.Core.pas e src/Horse.Instance.pas.
  • Tratamento de Métodos Anônimos: O FPC não suporta closures/métodos anônimos inline (procedure begin end). Introduzimos o método privado EmptyNext para gerenciar callbacks de resposta vazios sem causar erros sintáticos de compilação.
  • Remoção de Closures nos Roteadores: Refatoramos o Radix Router, RouterTree e NextCaller substituindo métodos anônimos por variáveis locais de thread (threadvar GCurrentExecutor, GCurrentNext, GCurrentNextCaller) e classes executoras dedicadas, mantendo o ecossistema thread-safe e compatível com compilação pura em Lazarus/Linux.
  • Operador de Conversão Implícita: Ajustamos o parser de callbacks no método GetCallback de src/Horse.Instance.pas utilizando typecast explícito THorseCallback(ACallbackRequest) para satisfazer o compilador FPC.

2. Estabilização da Suíte de Testes

  • Concorrência de Sockets Locais: Reestruturamos o teste físico de integração TestMultiInstanceRoutingIsolation em tests/src/tests/Tests.Integration.MultiInstance.pas para inicializar e finalizar os servidores em portas paralelas de forma sequencial. Isso evita colisões de portas físicas do sistema operacional decorrentes da arquitetura singleton estática clássica dos provedores standalone do Horse.

3. Usabilidade e Didática dos Exemplos (Samples)

  • Loops Não Bloqueantes: Atualizamos os exemplos de console em Delphi e Lazarus para usar IsConsole := False no escopo inicial. Isso permite que os métodos Listen retornem o fluxo de execução imediatamente para a Thread Principal, ativando os sockets em background nos provedores e permitindo gerenciar o encerramento do console com um Readln limpo, sem a necessidade de criação manual de threads (TThread).
  • Suporte a Execuções em Background: Adicionamos a switch --delay nos executáveis de amostra. Se detectada, os servidores aguardam 10 segundos antes de encerrar, permitindo testes automatizados de requisição física sem bloqueio interativo de teclado.

🌐 Comportamento de Rede: Standalone Sockets vs. Servidores Gerenciados

Como os provedores locais standalone do Horse (Indy, IOCP, HttpSys) utilizam estruturas singleton de classe, a execução simultânea concorrente de múltiplos listeners de socket físicos na mesma aplicação standalone não é suportada por design devido a colisões de bindings locais do SO.

Contudo, a arquitetura THorseInstance atinge sua totalidade de uso em Servidores Web Gerenciados (como IIS via DLL ISAPI, Apache via mod_delphi, CGI ou FastCGI):

  1. O servidor web externo (IIS/Apache) escuta fisicamente nas múltiplas portas (ex: porta 80 para API pública e 8080 para módulo Admin) e repassa os requests para o processo do Horse.
  2. A requisição chega ao THorseWebModule contendo o cabeçalho Request.ServerPort preenchido.
  3. O Horse resolve o contexto chamando GetHorseInstanceByPort(LPort) e direciona o fluxo para a árvore de rotas isolada daquela instância, garantindo 100% de isolamento e independência de middlewares sem conflito de concorrência de sockets locais.

Esta distinção foi documentada em detalhes na nova seção de infraestrutura em doc/multi-instance.md e doc/multi-instance.pt-BR.md.


🧪 Validação dos Testes

Foram executados e passaram com 100% de sucesso (Zero erros) os seguintes testes:

  1. Testes de Integração FPC (Linux/Docker):
    • Compilação limpa do projeto de testes em Linux 64-bit.
    • Execução e validação de todos os middlewares padrão e integridade.
  2. Suíte Geral Delphi (Windows - 10 Seattle até 13 Florence):
    • 164 testes unitários/integração validados em todas as instalações locais em todos os defines de provedores (Default, Default+Radix, HttpSys, HttpSys+Radix, IOCP, IOCP+Radix).
  3. Teste de Integridade da Fachada Clássica:
    • Execução do script tests/run_quick_test.ps1 atestando que a fachada THorse estática clássica (modo antigo) continua preservada.
  4. Teste Físico E2E:
    • Execução do script tests/run_e2e_integration_tests.ps1 atestando as chamadas e respostas HTTP reais via Invoke-RestMethod no exemplo de multi-instâncias e no servidor de integração clássico.

📂 Arquivos Modificados / Adicionados

  • Core & Instâncias:
    • src/Horse.Core.pas — Tratamento de loops de hooks atômicos sob FPC.
    • src/Horse.Instance.pas — Operações atômicas, callbacks e typecast sob FPC.
    • src/Horse.Core.Router.Radix.pas — Threadvars e executors para Radix Router sob FPC.
    • src/Horse.Core.RouterTree.pas — Threadvars e executors para RouterTree clássico sob FPC.
    • src/Horse.Core.RouterTree.NextCaller.pas — Isolamento de NextCallers sob FPC.
  • Testes:
    • tests/src/tests/Tests.Integration.MultiInstance.pas — Sequenciamento de sockets locais.
    • tests/run_quick_test.ps1 — [NOVO] Script de compilação rápida de integridade.
    • tests/run_e2e_integration_tests.ps1 — [NOVO] Script de testes de integração E2E físicos.
  • Documentação & Exemplos:
    • README.md / README.pt-BR.md — Inclusão do link da nova documentação.
    • doc/multi-instance.md / doc/multi-instance.pt-BR.md — [NOVO] Manuais de referência de instâncias.
    • doc/roadmap/prioritization_matrix.md — Atualização do status para Concluído.
    • samples/delphi/console_multi_instance/ConsoleMultiInstance.dpr — Exemplo Delphi simplificado.
    • samples/lazarus/console_multi_instance/ConsoleMultiInstance.lpr — Exemplo Lazarus simplificado.

@regyssilveira
regyssilveira merged commit 6ad0d99 into HashLoad:master Jul 10, 2026
@regyssilveira
regyssilveira deleted the feature/multi-instance branch July 10, 2026 22:23
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.

1 participant