Skip to content

Observation registration is per-webview, so independent callers in one window collide #57

Description

@jjhafer

ObserverRegistrations keys registrations by webview label
(src/subscriptions.rs:257), so two independent frontend modules in the same
window that each call observe() collapse into a single registration. The first
one to call unobserve() hits remaining == 0 and triggers full teardown
(src/commands.rs:900-904), aborting the other module's subscriptions — #54's
symptom, in-window.

PR #55 documents this as a caller obligation (a window needs a single owner of the
observe/unobserve pair) and #55's subscribe() registration check does not help:
both modules share the label, so both pass it.

Note on the obvious fix: adding webview_label to ActiveSubscription and
scoping teardown by it does not fix this case. Both modules share the label, so
a label-scoped remove_for_db aborts the identical set — and teardown also calls
disable_observation(), which sets observer = None
(crates/sqlx-sqlite-toolkit/src/wrapper.rs:449-451) and drops the broker, so
every stream ends regardless. Scoping would leave the second module's dead entry
behind until self-reap, i.e. strictly less cleanup for no benefit.

Possible approaches

  • A per-caller registration token returned by observe() and passed to
    unobserve(), replacing label-keyed refcounting.
  • A JS-side refcount in guest-js. Needs a module-level registry, because
    Database.get() returns a fresh instance per call
    (guest-js/index.ts:861-862), so per-instance state would not be shared.

Both are public-API changes, hence out of scope for #55.


Split out of the code review on #55, where it was validated as real but out of scope for that PR. See the review threads there for the supporting analysis.

Issue filed by AI model Claude

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions