Hero RPC Server's should use zinit for lifecycle and development #7
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
For instance in start command, should start itself via zinit.
<some_service>_server startshould start that server using zinit, from the current zinit progress ingeomind_code/zinitdevelopment_kristofbranch. This means generatedhero_rpcservers should be generated with such code to enable this.Use Zinit in Hero RPC Serverto Hero RPC Server's should usezinitfor lifecycle and developmentImplementation Plan: Zinit Lifecycle Integration for hero_rpc
Context
All generated hero_rpc servers should use zinit (via
ZinitRPCAPIClientfromgeomind_code/zinitdevelopmentbranch) for lifecycle management. This follows Pattern B (centralized orchestration via OpenRPC client) — the standard for all hero services going forward.Architecture
Where:
packages/oserverin hero_rpc — this is the high-level server wrapper that generated servers use. The code generator (packages/osis/src/generators/) will producemain.rsfiles that leverage this.Model: Full action+service registration using zinit's action-based architecture:
ActionSpec(exec command, health checks, retry policy, env vars)ServiceConfig(references the action, defines dependencies)ZinitRPCAPIClientCLI Subcommands for Generated Servers
Every generated
<service>_serverbinary will support:startstoprunstatuslogsuizinitImplementation Steps
1. Add zinit_sdk dependency to
packages/oserverAlways-on (not feature-gated) — zinit is the standard lifecycle manager.
2. Create
packages/oserver/src/lifecycle.rsNew module providing:
ZinitLifecyclestruct — encapsulates zinit client connection and service registrationregister_service()— builds and registersActionSpec+ServiceConfigwith zinit<binary_path> run, health checks (Unix socket or HTTP), retry policy, environment forwardingstart_service()— callsservice_start()via RPCstop_service()— callsservice_stop()via RPCservice_status()— callsservice_status()/service_status_full()via RPCservice_logs()— callslogs_get()/logs_tail()via RPCopen_ui()— opens service admin URL in browseropen_zinit_ui()— opens zinit web UI for this service in browser3. Create
packages/oserver/src/cli.rsClap-based CLI parser that all generated servers embed:
4. Extend
OServer/OServerConfigservice_nameto config (used for zinit registration)socket_paths()method returning the Unix socket pathsrun_cli()method that parses CLI and dispatches to the right handlerrunsubcommand calls the existingrun()method (current behavior)ZinitLifecycle5. Update code generator
packages/osis/src/generators/rust/rust_server.rsandscaffold.rs:main.rscallsOServer::run_cli()instead of manually parsing argsrunpath does what currentmain()does (register domains, run server)ZinitLifecycle6. Health check strategy
The generated
ActionSpecwill include a health check pointing to the service's Unix socket:hero_socketsskill: all services MUST have/healthendpoint on their Unix socket7. Zinit socket connection
Use
ZinitRPCAPIClient::connect_socket()with auto-detection:~/hero/var/zinit/zinit.sockconventionZINIT_SOCKETenv var overrideWhat This Replaces
cargo runfor production —startvia zinit is the standardrunsubcommand preserved for local developmentAlignment with Skills
Services to Migrate (follow-up issues)
These existing services use older zinit patterns and should migrate to Pattern B:
hero_embedder_server— currently uses Pattern A (ServiceConfigBuilder + ZinitHandle)hero_books_server— currently uses Pattern C (CLI subprocess)Open Questions
startalso handle first-time setup (creating data dirs, seeding)? Or is that a separateinstallaction in zinit?Implementation Complete — Zinit Lifecycle Integration
What was done
All changes are on the
developmentbranch inhero_rpc.New files
crates/server/src/server/cli.rs—ServerCli+ServerCommandenum with 7 subcommands:start,stop,run,status,logs,ui,zinitcrates/server/src/server/lifecycle.rs—ZinitLifecyclestruct using Pattern B (ZinitRPCAPIClientfromzinit_sdkondevelopment_kristof)Modified files
crates/server/src/server/server.rs— AddedOServer::run_cli()entry point that dispatches CLI → lifecycle or direct runcrates/server/src/server/mod.rs— Exportscliandlifecyclemodulescrates/server/src/lib.rs— Re-exportsServerCli,ServerCommand,ZinitLifecyclecrates/server/Cargo.toml— Addedclap,zinit_sdk(development_kristof),opencrates/generator/src/build/scaffold.rs— Updated code generator: new projects useOServer::run_cli()with zinit lifecycle out of the boxDependency fixes
herolib_derive/src/rpc_proxy.rsondevelopment_kristof(commite519cb14)development_kristofbranch (commit56091f21)cargo check --workspacepasses)Usage pattern for generated servers
CLI commands:
hero_myservice_openrpc start— register with zinit + starthero_myservice_openrpc stop— stop via zinithero_myservice_openrpc run— direct mode (dev)hero_myservice_openrpc status— query zinit statushero_myservice_openrpc logs -n 50— fetch zinit logshero_myservice_openrpc ui— open admin UIhero_myservice_openrpc zinit— open zinit web UIVerification Plan
Tests to confirm issue #7 is resolved. All tests are in
crates/server/.1. Unit Tests (no zinit needed)
test_cli_parse_startServerCliparsesstartsubcommandtest_cli_parse_stopServerCliparsesstopsubcommandtest_cli_parse_run_defaultsrundefaults: contexts="root", no seed_dir/seed_domainstest_cli_parse_run_customrun --contexts a,b --seed-dir ./data --seed-domains d1,d2test_cli_parse_statusServerCliparsesstatussubcommandtest_cli_parse_logs_defaultlogsdefaults to 100 linestest_cli_parse_logs_customlogs -n 50parses correctlytest_cli_parse_uiServerCliparsesuisubcommandtest_cli_parse_zinitServerCliparseszinitsubcommandtest_lifecycle_newZinitLifecycle::new()sets defaults correctlytest_lifecycle_builder.context(),.description(),.run_args()test_lifecycle_exec_commandexec_command()builds correct command string with args2. Scaffold Tests
test_scaffold_openrpc_main_uses_run_cliOServer::run_clitest_scaffold_openrpc_cargo_has_server_dephero_rpc_serverdependencytest_scaffold_openrpc_main_has_importshero_rpc_server::OServer3. Integration Tests (require zinit running — CI only)
Not implemented in this PR — these require a running zinit instance. Will be added when CI has zinit available.
How to run
Verification Results
All changes pushed to
developmentbranch (commitsc312c00and79dea33).Test Results
Pre-existing test fixes included
use crate::SchemaExtimportdb/tests.rsWhat was verified
OServer::run_cliin main.rshero_rpc_serverdependencycargo check --workspace)hero_os has adopted
OServer::run_cli()incrates/hero_os_server/src/main.rs. However the Makefile and README were never updated — they still document the oldmake run/make servicepattern. Cleaning those up now to reflect the new lifecycle model.Fixed the default zinit socket path in
ZinitLifecycle::connect()— was~/hero/var/zinit/zinit.sock, should be~/hero/var/sockets/zinit_server.sockto matchzinit_server's actual bind path. Pushed asd18ef03.Also established best practices for repos adopting this pattern:
runsubcommand is internal (zinit calls it). Devs usestart/stop/status/logs.cargo updatebefore start:make startrunscargo updatefirst so git deps are fresh.make run= start + stream logs: Starts via zinit, streams logs in foreground, Ctrl-C stops services. Best DX while keeping zinit supervision.hero_os_ui) should importZinitLifecyclefromhero_rpc_server.Naming Convention Finalized
The CLI subcommand naming is now standardized across all hero_rpc-based servers:
runstartstopservestatuslogsImplementation
ZinitLifecycle::run()method added — handles start + log streaming + Ctrl-C stopZinitLifecycle::exec_command()now generates{binary} serve(wasrun)ServerCommand::Servereplaces oldServerCommand::Run(aliased as_serve)ServerCommand::Rundispatches tolifecycle.run()Makefile best practice
No Makefile-level log polling needed —
ZinitLifecycle::run()handles everything.Commit:
9d338adServe Rename Applied to All 4 Non-OpenRPC Repos
The
run → serverename convention from commit9d338adhas been applied to:development_standardizebranch, commit415ac19)developmentbranch, commit0351b0d)developmentbranch, commitf3ae5d6)developmentbranch, commitabecd5f)All 4 repos now use the same pattern as the hero_rpc framework:
runstartstopservestatus/logsSince these repos don't use OSIS/OpenRPC, they use a local
ZinitLifecycle(same API ashero_rpc_server::ZinitLifecycle) withzinit_sdkdirectly.All compile clean. Details in lhumina_code/home#6