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

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions