Skip to content

Feature/server lifecycle - #518

Merged
regyssilveira merged 3 commits into
HashLoad:masterfrom
regyssilveira:feature/server-lifecycle
Jul 11, 2026
Merged

Feature/server lifecycle#518
regyssilveira merged 3 commits into
HashLoad:masterfrom
regyssilveira:feature/server-lifecycle

Conversation

@regyssilveira

Copy link
Copy Markdown
Contributor

Pull Request: Unified Server Lifecycle Hooks, Graceful Shutdown, and Multi-Instance Sockets

Description

This pull request introduces a cohesive alignment and robust implementation of Server Lifecycle Hooks, Graceful Shutdown, and Multi-Instance Sockets across all 14 network transport providers (covering Delphi, FreePascal, Windows, Linux, and IIS hosts).

It resolves dangling pointer bugs, provides compatibility with FreePascal compilers (Linux ELF builds), adds structured bootstrapping support via UseStartup / IHorseStartup, and resolves a legacy limitation in the Indy Console Provider, allowing it to bind to multiple concurrent ports on a single process.


Key Modifications

1. Unified Lifecycle Hooks & Multi-Instance Resolution

  • Moved and triggered TriggerBeforeListen and TriggerBeforeStop callbacks at the transport layer of all providers.
  • Overrode GetActivePort class methods globally to enable dynamic instance routing.
  • Added dangling pointer protection on THorseInstance.Destroy (UnregisterHorseInstance) preventing random Access Violations (offset D408) during cleanup.

2. Multi-Port Bindings Support for Indy

  • Updated the Indy Console Provider (Horse.Provider.Console.pas) to iterate dynamically over GInstances keys and map multiple TIdSocketHandle bindings.
  • Added a reset trigger (Active := False -> Active := True) to reconstruct active sockets on concurrent instance listen calls.
  • Result: Multi-Instance applications on Indy now successfully bind to distinct physical ports (e.g. 9001 and 9002 concurrently) within the same process.

3. Structured Bootstrapping (Startup App)

  • Implemented the ASP.NET Core-like structured bootstrapping pattern using UseStartup and IHorseStartup.
  • Created a complete console demo project: ConsoleUseStartup.dpr.

4. Cross-Platform FPC Compatibility

  • Adjusted the declaration of THorseServerLifecycleProc in Horse.Instance.pas to support classic method pointers on FPC (which does not support anonymous methods / reference to procedure).

5. Documentation Updates

  • Lifecycle & Graceful Shutdown: Updated lifecycle-hooks.pt-BR.md and graceful-shutdown.pt-BR.md.
  • Getting Started (UseStartup): Added structured bootstrapping guides to getting-started.pt-BR.md and getting-started.md.
  • Multi-Instance Matrix: Created a provider/router compatibility matrix under multi-instance.pt-BR.md and multi-instance.md.

Verification and Integration Testing

Automated Test Suite (Windows)

All 168 unit tests passed with 0 memory leaks:

==========================================================
  TESTE CONCLUÍDO COM SUCESSO! FACHADA CLÁSSICA PRESERVADA
==========================================================
End-to-End Integration Tests (Delphi / Windows)
Executed run_e2e_integration_tests.ps1 with success:

Fase 1 (Multi-Instance):
* [GET] http://127.0.0.1:9001/api/v1/ping -> 'Pong da API Publica (Instancia 1)' (Pass)
* [GET] http://127.0.0.1:9002/admin/ping -> 'Pong da Area Admin (Instancia 2)' (Pass)
* [GET] http://127.0.0.1:9001/admin/ping -> 404 Not Found (Isolation Pass)
Fase 2 (Classic Server):
* [GET] http://127.0.0.1:9999/ping -> 'pong' (Pass)
* [GET] http://127.0.0.1:9999/secure/private -> 401 Unauthorized (Pass)
* [GET] http://127.0.0.1:9999/secure/private -> 'private-ok' (Pass)
End-to-End Integration Tests (Lazarus / Ubuntu Linux)
Built and executed the FPC integration server via Docker container (tests-lazarus service using Epoll Provider on Ubuntu 22.04):

GET /ping -> 200
GET /private (No Auth) -> 401
GET /private (With Auth) -> 200
POST /echo (Johnson Parser) -> 200
INTEGRATION TEST: SUCCESS (ALL MIDDLEWARES) (Pass)

@regyssilveira
regyssilveira merged commit 0a00b5a into HashLoad:master Jul 11, 2026
@regyssilveira
regyssilveira deleted the feature/server-lifecycle branch July 11, 2026 02:37
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