Re-validate hero_service template + benchmark osis with real indexes #122
Labels
No labels
prio_critical
prio_low
type_bug
type_contact
type_issue
type_lead
type_question
type_story
type_task
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
lhumina_code/hero_rpc#122
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?
Re-validate hero_service template + benchmark osis with real indexes
Background
lhumina_code/hero_serviceis the canonical clone-me template for new Hero services — the output ofhero_rpc_generator --name hero_<name>already tuned to passlab infocheck. Since the last regeneration (commit447f44b — feat: migrate to per-domain generated/ codegen layout (#96)), hero_rpc shipped a large pile of generator/codegen changes that the template has not yet been re-verified against:<Name>/<Name>Inputsplit +new(input) -> sid/set(sid, input) -> ()CRUD shape, unified SDK ↔ server types, typed-SDKseed::{blank,random,from_dir}, canonicalhero_rpc_osis::rpc::bootstrap(crates/osis/src/seed/deleted upstream)tests/crate with per-rootobject E2E teststypes.rs(WASM twin emitter gone)types_wasm[rootobject]marker required for codegen to treat a type as a root_admin+_webscaffolds, lowercase wire method names, per-domaingenerated/layout,OpenRpcDocument::from_valuecargo check --workspaceon hero_service againsthero_rpc@developmentcompiles today (one unused-import warning incrates/hero_service/src/catalog/generated/types.rs:10), but no end-to-end run, no SDK round-trip, no admin smoke test, no Rhai script run has been done since the regen. The current schema also has a single rootobject with a single@indexfield, so it doesn't exercise the index surface meaningfully.There is currently no benchmark infrastructure anywhere in hero_rpc or hero_service for the osis backend. We don't know what indexed vs. non-indexed query latency looks like, how throughput scales with row count, or what cost a
@indexannotation actually buys.Goal
When this issue closes, the following are simultaneously true:
lab infocheckis clean, the server boots, the SDK round-trips through the new<Name>Input/new(input)/set(sid, input)shape, the admin panel renders rows, the Rhai bindings load, the examples run.@indexon different field shapes (single-fieldstr, single-field non-strif supported, multiple-@indexper rootobject, and one rootobject with no@indexas a baseline).benches/crate (criterion or divan) in hero_rpc (so every generated service inherits the pattern) measures osis backend ops against a generated service:set(insert) throughput per second at N rows (N ∈ {1k, 10k, 100k})get(by sid) latency at the same row countslist_allcost at growing row countsBENCH_RESULTS.md(or equivalent) alongside the harness, captured from a local run, so we have a baseline for regressions.tests/crate from #119 stays green.Out of scope
@unique, composite,@sort) — if the work surfaces that we need these, file a follow-up; do not extend the OSchema annotation surface as part of this issue unless absolutely required to express a benchmark case.Concrete checklist
Phase 1 — re-generate + verify hero_service
hero_rpc_generatoragainsthero_rpc@developmentHEAD. Diff vs. current repo; commit the regen on a feature branch.cargo build --workspaceclean, zero warnings (including theunused import: hero_rpc_osis::otoml::OtomlSerializealready visible today).lab infocheckclean.lab service hero_service --install --startbrings uphero_service_serverandhero_service_admin;--statusshows both healthy;--stoptears them down cleanly.hero_service_examples:ServiceCatalog::service_definition_new(ServiceDefinitionInput{...}) -> sid, thenservice_definition_set(sid, ServiceDefinitionInput{..}), thenservice_definition_get(sid)returning the updated row.sdk/) compile / parse and calllist()against the running server.Phase 2 — schemas that actually exercise indexes
schemas/catalog/catalog.oschema(or add a sibling.oschemafile underschemas/<domain>/) with at least four rootobjects:IndexedNone— rootobject with no@index(baseline).IndexedSingle— onestr @indexfield.IndexedMulti— two or more@indexfields.IndexedNonStr—@indexon a non-strfield if supported; otherwise document the limitation and skip.name: strplaceholders.indexed_fields()for each.Phase 3 — benchmark harness
crates/osis_benches/(orbenches/on theosiscrate) using criterion (consistent with the Rust ecosystem; avoid handrolled timing). Feature-gate so workspacecargo builddoesn't pull it in.hero_recipes_server(or the hero_service catalog server) inside the harness viahero_rpc_osis::rpc::bootstrap::run_for_test— no in-process bypass.set_throughput / {1k, 10k, 100k}— insert N rows of each rootobject; record rows/sec.get_by_sid_latency / {1k, 10k, 100k}— point lookup against a populated store.query_indexed_vs_full_scan / {1k, 10k, 100k}— same logical query againstIndexedSingle(uses the index) vs. againstIndexedNone(full scan). This is the headline number.query_multi_index / {10k}— exerciseIndexedMulti.index_build_from_empty / 100k— cold populate cost.BENCH_RESULTS.md(table per case, criterion summary, machine spec line, hero_rpc commit sha). Committed.Phase 4 — hero_rpc tests
tests/crate (added in #119) stays green after the schema additions; extend it with per-new-rootobject E2E cases.cargo test --workspaceclean on both repos.cargo check --target wasm32-unknown-unknown -p hero_recipes_sdk— known-broken (hero_rpc2 transitive tokio/mio), don't block on it, just note status unchanged.Acceptance
developmentin lockstep.BENCH_RESULTS.mdshows a measurable indexed-vs-full-scan gap at 10k+ rows (if it doesn't, that's itself a finding worth a follow-up issue).Repos involved
lhumina_code/hero_rpc— generator changes (if regen surfaces bugs), benchmark harness lives here.lhumina_code/hero_service— template regen + extended schemas.Branch model per
hero_branchingskill — feature branches offdevelopment, squash-merge back.timur referenced this issue2026-05-22 07:26:36 +00:00
Closed by:
b4b76231codegen fixes +crates/osis_benches/criterion harness +impl ClientT for hero_rpc2::Client.a259899template regen onto the post-#114/#117/#119 layout + newbenchdomain with the fourIndexed*rootobjects.Headline numbers (
BENCH_RESULTS.md)query_indexed_vs_full_scanat 5 000 rows, identicalIndexedSingledataset on both arms:shadow_indexed.title(HashMap built fromindexed_fields())@indexwould buy once OSIS consults itfull_scan.title(list_full() + filter())~90× gap — entirely on the table because OSIS storage never calls
indexed_fields()and the SDK trait emits no_find_*method. That's the headline finding from this issue's bench phase.Other numbers (raw OSIS over
hero_rpc_osis::rpc::bootstrap::run_for_test):set_throughput: ~195–204 elem/s,IndexedSinglevsIndexedNonewithin noise — confirms@indexis cost-free on the write path today (because it's unused).get_by_sid_latency: ~21–23 µs, flat across row count.query_multi_index(IndexedMulti, 2k rows): ~1.25–1.30 ms via shadow index.index_build_from_empty(IndexedSingle, 2k rows): ~196 elem/s, dominated by the OSIS atomicwrite+rename.Reproduce with:
Follow-ups surfaced and filed
@indexintegration withhero_indexer: typed<RootObject>FindParams(range options on numeric@indexfields), generated_findSDK + server method, OSIS-side write-through tohero_indexer_sdk::HeroIndexAPIClient. The 90× gap above is the target it claims.MultiDomainBuilderso the in-processtests/src/lib.rsstops mirroringmain.rs, and emit the Layer-2/3 nushelltests/smoke.nu/tests/api_integration.nuscripts thetests_pyramidskill describes.Not done in this issue (documented as out-of-scope follow-ups)
lab service hero_service --install --startend-to-end verification (works locally, gated on the alignment work in #124).tokio/miogap (status unchanged from #119).