Files
Joseph Doherty d149143535 [F49 steps 2 + 3] live verification: buffered recovery replay + unsubscribe skip
Step 3 (F47 buffered unsubscribe skip):
- crates/mxaccess-compat/tests/buffered_unsubscribe_skip_live.rs.
- Subscribe buffered, sleep so the engine has DataUpdates in flight,
  then call unsubscribe. Asserts Ok return without surfacing transport
  or HRESULT errors.
- Session::unsubscribe (session.rs:2261) probes the registry: if
  Buffered { .. }, it skips nmx.un_advise entirely, mirroring the .NET
  reference's `if (!subscription.IsBuffered)` guard at
  MxNativeSession.cs:361-381. If unsubscribe accidentally emitted
  UnAdvise for a buffered correlation id, the engine would return
  non-zero HRESULT (no matching plain advise to retract) — surfacing
  as a panic.

Step 2 (F45 buffered recovery replay):
- crates/mxaccess-compat/tests/buffered_recovery_replay_live.rs.
- Subscribe buffered, drain >=1 NMX subscription message
  (cmd=0x32 SubscriptionStatus + cmd=0x33 DataUpdate) to confirm the
  wire path is hot pre-recovery, install a RebuildFactory that calls
  NmxClient::create (the same auto-resolving COM-activation path
  Session::connect_nmx_auto uses), invoke recover_connection, drain
  >=1 NMX subscription message post-recovery.
- Verifies the replay branch in recover_connection_core re-issues
  RegisterReference (NOT AdviseSupervisory) for the buffered entry,
  mirroring MxNativeSession.ReAdviseSubscription (cs:538-569).
  Structural property is unit-tested; this confirms the engine
  actually picks back up after the rebuild + replay.

Both tests pass live on this Galaxy:
  cargo test -p mxaccess-compat --features live-windows-com \
      --test buffered_unsubscribe_skip_live -- --ignored --nocapture
  cargo test -p mxaccess-compat --features live-windows-com \
      --test buffered_recovery_replay_live -- --ignored --nocapture

Pulls mxaccess-nmx + mxaccess-codec into mxaccess-compat dev-deps so
the recovery test can build a RebuildFactory closure that returns
NmxClient and bind a typed broadcast Receiver.

design/followups.md F49 -> Resolved (all five steps pass live).
docs/M6-live-verification.md updated with per-step evidence + repro
commands.

F49 is fully closed out. F55 (DCOM-managed INmxSvcCallback, Path A)
and F56 (missing EnsurePublisherConnected + post-RegisterReference
AdviseSupervisory for buffered) were the two real Rust-port bugs
uncovered along the way; both resolved. Remaining post-V1 followups
(F50 Suspend/Activate Frida, F51 ASB type matrix, F52 perf, F53 doc
lint, etc.) are scoped independently and not part of F49.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-06 12:00:44 -04:00

57 lines
2.7 KiB
TOML

[package]
name = "mxaccess-compat"
description = "LMXProxyServer-shaped Rust facade on top of `mxaccess::Session`. Optional / post-V1."
version.workspace = true
edition.workspace = true
license.workspace = true
repository.workspace = true
rust-version.workspace = true
authors.workspace = true
[dependencies]
mxaccess = { path = "../mxaccess", version = "0.0.0" }
tokio = { workspace = true }
tokio-stream = { version = "0.1", features = ["sync"] }
futures-util = { workspace = true }
thiserror = { workspace = true }
# F49 step 4 — F40 metrics live smoke. Optional; only pulled in when
# the `live-metrics` feature is on (or transitively via the test
# binary that exercises it).
metrics = { workspace = true, optional = true }
metrics-exporter-prometheus = { version = "0.16", default-features = false, optional = true }
[dev-dependencies]
tokio = { workspace = true, features = ["macros", "rt", "rt-multi-thread", "sync", "time"] }
async-trait = { workspace = true }
mxaccess-rpc = { path = "../mxaccess-rpc", version = "0.0.0" }
# F56 — buffered subscribe live test needs real Galaxy DB metadata
# (engine_id / platform_id / object_id / attribute_id from
# `dbo.gobject` etc.); the StaticResolver shim used by lmx_write_live
# was hardcoded to platform_id=1 / engine_id=2 which the engine
# silently accepts for writes but doesn't dispatch DataUpdate frames
# against. The buffered live test resolves real IDs via SqlTagResolver.
mxaccess-galaxy = { path = "../mxaccess-galaxy", version = "0.0.0", features = ["galaxy-resolver"] }
# F49 step 2 — recovery replay test needs the
# `mxaccess::RebuildFactory` typedef's NmxClient + the
# NmxSubscriptionMessage type for the broadcast receiver signature.
mxaccess-nmx = { path = "../mxaccess-nmx", version = "0.0.0", features = ["windows-com"] }
mxaccess-codec = { path = "../mxaccess-codec", version = "0.0.0" }
# Live tests use tracing-subscriber to dump router/dcom_sink trace
# events on demand (set RUST_LOG=mxaccess=trace,mxaccess_callback=trace).
tracing = { workspace = true }
tracing-subscriber = { version = "0.3", features = ["env-filter"] }
[features]
default = []
# F49 / F54 live test gate. Enables `Session::connect_nmx_auto` for
# the live integration test at `tests/lmx_write_complete_live.rs`.
live-windows-com = ["mxaccess/windows-com"]
# F49 step 4 — F40 metrics live smoke. Pulls metrics-exporter-prometheus
# + the mxaccess `metrics` feature so a live test can install a real
# recorder, drive Session::write, and assert counter increments +
# histogram observations land via the wired call sites.
live-metrics = ["mxaccess/metrics", "mxaccess/windows-com", "dep:metrics", "dep:metrics-exporter-prometheus"]
[lints]
workspace = true