77: Make NenjimHub the runtime owner and replace NenjimApplication with NenjimProcess

This commit is contained in:
2026-09-02 15:59:56 +02:00
parent a252c256c4
commit f5fc5bb3b5
29 changed files with 1012 additions and 461 deletions
+28 -13
View File
@@ -183,32 +183,47 @@ hints kan på sigt foretrække en lavere kompatibel release.
## 8. Componenter og det centrale Registry
En Nenjim component er en færdigkonstrueret byggeklods, som er klar til brug. Rollen som service, applikation,
algoritme eller adapter bestemmes af den applikation, som bruger componenten; Registry-API'et bruger derfor det
fælles ord `component` og ikke `plugin`. `NenjimComponent` er en ren marker interface. En startbar component kan
desuden implementere `NenjimApplication`, som kun lover `start()` og ikke en fælles stop-operation.
algoritme eller adapter og klassifikationen som aktiv proces er uafhængige dimensioner. En service eksponerer et
domain API, mens en applikation beskriver en user-facing eller orchestration-rolle. Registry-API'et bruger det
fælles ord `component` og ikke `plugin`, og `NenjimComponent` er en ren marker interface. En component, som Hub'en
kan starte og tracke, implementerer desuden den canonical `com.r35157.nenjim.process.NenjimProcess`, som kun lover
`start()` og ikke en fælles stop-, restart- eller health-operation. En service- eller applikationsimplementation kan
derfor også være en process; passive componenter er det ikke.
En `NenjimComponentId` er registration metadata i ét Registry og er ikke en egenskab ved objektet. ID-formatet er
lower-case ASCII med dot-separated segments og valgfrie interne bindestreger, f.eks. `nenjim.registry.service` og
`assetaz.price-source.raydium-pool.eve-usdt`. Det samme objekt må registreres under flere forskellige ID'er, og én
registration bliver automatisk synlig gennem alle component interfaces, som objektet implementerer. Registry- og
application-view af Registry-objektet har derfor samme ID og samme object identity.
registration bliver automatisk synlig gennem alle component interfaces, som objektet implementerer. Registry-
service- og process-view af Registry-objektet har derfor samme ID og samme object identity.
`NenjimRegistryService` er det read-only katalog, som almindelige consumers modtager gennem constructor injection.
Det kan returnere et immutable registration-order snapshot af ID'er for et component interface eller slå ét ID op
gennem et forventet interface. Et manglende ID giver `null`; et eksisterende ID med forkert interface er en caller
programming error. Public API'et kan ikke registrere eller fjerne componenter.
`NenjimRegistryServiceManagerImpl` konstruerer og starter Registry'et, registrerer Registry og manager først og
konstruerer derefter den nuværende hardcodede component graph i dependency order. Den package-private admin-view er
kun managerens registrationshandle og er hverken en component eller public API. Registration starter ikke et
objekt, og Registry'et forbliver internt åbent for senere registration efter startup.
`NenjimHubImpl` repræsenterer én kørende Nenjim runtime. Hub'en konstruerer Registry-subsystemet og hele den
nuværende hardcodede component graph, ejer dependency wiring og vælger de processer, som skal startes. Et
implementation-only Registry assembly udleverer read-only service-view, process-view af det samme Registry-objekt
og en separat `NenjimRegistryServiceManager`. Manageren er kun Hub'ens passive registrationshandle: den er hverken
component eller process, har ingen `start()` eller service-accessor, registreres ikke og starter aldrig en component.
Den package-private `NenjimRegistryServiceAdmin` er managerens interne mutationsadgang. Den må ikke gøres public,
fordi almindelige consumers ellers kunne caste deres Registry-service til mutationsinterfacet og bryde det
read-only service contract. Registration starter ikke et objekt, og Registry'et forbliver internt åbent for senere
registration efter startup.
Applikationen ejer sine konkrete valg og sin activation. Tickerens initiale configuration vælger eksplicit
`assetaz.price-source.raydium-pool.eve-usdt` gennem Registry'et; den hardcodede price source er registreret, men
inaktiv. Manageren starter kun den nuværende eksplicitte, dependency-safe liste: Ticker, Production Evelyn, Test
Evelyn, Production IOU Burner og Mission Control. Alarmen og øvrige tidligere udkommenterede applikationer bliver
ikke automatisk aktiveret. `com.r35157.nenjim.hubd.Main` er kun det yderste Java-bootstrap; `Main.main(...)` starter
manageren gennem `NenjimApplication` og er ikke selv en component eller applikation.
inaktiv. Hub'en starter Registry-processen først og registrerer den som `nenjim.registry.service`. Derefter starter
Hub'en kun den nuværende eksplicitte, dependency-safe liste: Ticker, Production Evelyn, Test Evelyn, Production IOU
Burner og Mission Control. Alarmen og øvrige tidligere udkommenterede applikationer bliver ikke automatisk
aktiveret. Efter hvert succesfuldt `start()` registrerer Hub'en process-ID'et i et immutable, ordered snapshot; et
fejlet start bliver ikke registreret, og listen lover ikke fortsat health eller liveness. Startup er fail-fast og kan
kun forsøges én gang uden generic rollback.
`com.r35157.nenjim.hubd.Main` er kun det yderste Java-bootstrap. `Main.main(...)` konstruerer `NenjimHubImpl` gennem
det globale `NenjimHub`-interface og kalder `start()` præcis én gang. Hub'en ejer også det eksisterende online point
og den afsluttende blocking wait. Hub'en er hverken component eller process og registreres ikke i sit eget Registry.
Det implementerede Registry er ét katalog og er ikke et authorization-system. Contexts, artifact-version semantics,
resolution, classloading, automatic discovery, public runtime loading/registration, removal, persistence, events,