Skip to content

Support multiple state objects / subsystems per library #96

Description

@gmelodie

Problem

A library is bound to exactly one state type. declareLibrary(name, LibType, defaultABIFormat) records a single currentLibType; FFIContext[T] has one myLib: ptr T; ffiThreadBody instantiates one var ffiReqHandler: T. A node exposing relay + filter + store must cram all of it into one T. Lowest priority / largest design surface — treat as exploratory. {.ffiHandle.} types (FFIHandleRegistry) already provide a secondary id-keyed object mechanism.

Proposal (pick based on how much the single-type limit actually hurts)

7a — lean on handles (recommended first, minimal change). Keep one small root T (a registry/facade); each subsystem is an {.ffiHandle.} object created via a {.ffi.} proc returning a handle id; subsystem methods take the handle as first object param (already supported — ridesAsPtr/isHandle in meta.nim, FFIHandleRegistry in ffi_handles.nim). Deliverable is mostly docs + a codegen nicety: generate a wrapper class per handle type so callers see node.relay().subscribe(...) instead of free functions taking an opaque id. Zero core-architecture risk; likely the right answer.

7b — true multi-state context (larger, only if 7a is insufficient). declareLibrary accepts multiple state types into a keyed registry; FFIContext holds a heterogeneous set (compile-time tuple or Table[TypeId, pointer]); ffiThreadBody instantiates each; processRequest resolves each proc's state type. Ripples into ffi_context_pool.nim, every ptr FFIContext[T] signature, and codegen receiver resolution — the highest-churn change in the set.

Gotchas

  • Handles already solve "multiple live objects of the same kind" — confirm the real requirement is "multiple kinds of root state" before paying 7b's cost. Do not start with 7b.
  • All subsystems share the one FFI thread / chronos loop. A subsystem needing its own thread is a different feature (separate contexts) — don't conflate.

Tests

  • 7a: an examples/ multi-subsystem library + e2e C++ test exercising two handle types from one context.
  • 7b: per-state routing test; pool acquire/release with multi-state contexts; full sanitizer pass (the generic change is leak-prone).

Effort: small for 7a (docs + a codegen grouping pass), large/invasive for 7b. Recommendation: ship 7a; revisit 7b only if a concrete consumer hits a wall handles can't model.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions