Skip to content

edge: D2D parity for peer lifecycle @on handlers#33

Merged
soupat merged 1 commit into
mainfrom
sourav/peer-lifecycle-d2d-rebase
May 13, 2026
Merged

edge: D2D parity for peer lifecycle @on handlers#33
soupat merged 1 commit into
mainfrom
sourav/peer-lifecycle-d2d-rebase

Conversation

@soupat
Copy link
Copy Markdown
Collaborator

@soupat soupat commented May 13, 2026

Summary

  • Deliver @on(event_name="peer_present"|"peer_lost") handlers via PresenceCollector callbacks when a D2D collector is present, so D2D drivers see the same lifecycle events as registry-mode drivers (which already get them through edge: support lifecycle event subscriptions and glob device_id filters #27's broker subject).
  • PresenceCollector gains symmetric on_peer_removed support and a multi-listener model (back-compat with the existing collector._on_new_peer = ... pattern in device.py).
  • 9 new tests; existing @on and registry-mode behavior unchanged.

Background

This is the rebased content of PR #31, which was merged into the now-orphaned stacked base branch feat/peer-lifecycle-events after #27 squash-merged to main first. The diff against main is the same 390 LOC as before.

How

discovery.py:

  • PresenceCollector grows symmetric on_peer_removed support (fires on departing: true graceful departure AND on prune-timeout in _prune_loop).
  • Multi-listener model: constructor-form on_new_peer / on_peer_removed kwargs still work as single-listener seeds; new add_on_new_peer / add_on_peer_removed methods append additional listeners. The existing collector._on_new_peer = ... pattern in device.py keeps working via a back-compat property.

drivers/base.py:

  • _setup_subscription checks self._device._d2d_collector for lifecycle aliases; if present, the handler is wired via the collector's new listener methods (_setup_lifecycle_d2d) instead of subscribing to the broker subject.
  • Per-device events are unaffected; still subscribe through the broker.

Glob and exact device_id= filters apply post-hoc inside the delivery wrapper (same _device_id_matches helper as #27).

Tests

9 new tests:

TestLifecycleSubscriptionsD2D
  test_peer_lost_routes_through_collector
  test_peer_present_routes_through_collector
  test_d2d_lifecycle_device_id_filter_exact
  test_d2d_lifecycle_device_id_filter_glob
  test_d2d_per_device_event_still_uses_broker

TestPresenceCollectorRemovedCallback
  test_graceful_departure_fires_on_peer_removed
  test_prune_timeout_fires_on_peer_removed
  test_add_on_peer_removed_supports_multiple_listeners
  test_constructor_callback_coexists_with_listeners

Test plan

…D mode

The registry publishes device.{online,offline} on a shared subject
per tenant; D2D mode has no registry, so subscribing to that subject
sees nothing. Wire @on(event_name='peer_present'|'peer_lost') through
PresenceCollector callbacks when a D2D collector is present on the
device runtime, so the same decorator gives the same behavior in
both modes.

PresenceCollector grows multi-listener support (backward compatible
with the constructor-form on_new_peer pattern; new add_on_new_peer /
add_on_peer_removed methods) and emits on_peer_removed from both the
graceful-departure branch and the prune-timeout loop.

Per-device event subscriptions are unaffected; they still go through
the broker subject in both modes.

9 new tests, 437 total passing.
@soupat
Copy link
Copy Markdown
Collaborator Author

soupat commented May 13, 2026

this was reviewed and merged but not on the main.

@soupat soupat merged commit 81fb15d into main May 13, 2026
9 checks passed
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