Skip to content

Add observer/observable pattern to device#7

Draft
bruno-f-cruz wants to merge 4 commits into
refactor-unified-apifrom
feat-device-event-logic
Draft

Add observer/observable pattern to device#7
bruno-f-cruz wants to merge 4 commits into
refactor-unified-apifrom
feat-device-event-logic

Conversation

@bruno-f-cruz

@bruno-f-cruz bruno-f-cruz commented Jul 4, 2026

Copy link
Copy Markdown
Member

Leaving this as a draft as it is a bit opinionated, but since I had this convo with @Poofjunior and @glopesdev separately, just putting it on a PR for future reference. This is how I would like to handle events from devices :P

I added a quick example that compares the two APIs

Summary

tldr: push over pull, reactive framework rocks.

Replaces the single overridable _on_event hook with a proper push-subscription API for device-emitted messages, delivered off the reader thread, plus an optional ReactiveX adapter.

What changed

  • Device.subscribe(register, handler, *, message_types=Event) — register a callback that receives a typed, parsed ParsedHarpMessage. Filters by message type (default: unsolicited Events only; opt into Read/Write replies). Returns a Subscription handle with unsubscribe() (also a context manager).
  • Device.subscribe_all(handler, ...) — catch-all across every address for logging/forwarding.
  • Reader thread stays lean. _dispatch correlates request/reply replies on the fast path (O(1), non-blocking) and fans every message onto a dedicated event thread. Handlers run there, so a slow handler can't stall synchronous read()/write(), and handlers may safely call back into the device.
  • close() clears subscriptions so a closed/reopened device retains no stale handlers.
  • Optional Rx adapter (harp.device.rx)observe() / observe_all() return hot, ref-counted (ops.share) Observables backed by a single underlying subscription. Gated behind the harp-device[rx] extra; importing the module without reactivex raises a clear ImportError. If i had it my way, we would only have this, but for now leaving it optional.
  • Examplescripts/event_monitor.py prints all events from a device on COM3.

Notes

  • Subscribers share one event thread → handlers are invoked sequentially, in order; keep them quick or offload with ops.observe_on(scheduler).

@bruno-f-cruz bruno-f-cruz marked this pull request as draft July 4, 2026 02:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant