Skip to content

[EXAMPLE] Using signals instead of callbacks#1154

Draft
Turnlings wants to merge 3 commits intomainfrom
1077-task-backend-publishersubscriber-architecture
Draft

[EXAMPLE] Using signals instead of callbacks#1154
Turnlings wants to merge 3 commits intomainfrom
1077-task-backend-publishersubscriber-architecture

Conversation

@Turnlings
Copy link
Copy Markdown
Contributor

@Turnlings Turnlings commented Apr 8, 2026

This is the basics of using signals, in its simplest form its easiest to just move what was the callbacks in utils to being handlers of their own route in signals.py

DroneConnectStatus is a full replacement of the old callback and so is the simplest example

DroneError shows two options, you can either directly send in each place you would have called the callback, or you can add a function to drone that essentially represents the old callback and you route all the calls through that.

Copilot AI review requested due to automatic review settings April 8, 2026 21:47
@Turnlings Turnlings linked an issue Apr 8, 2026 that may be closed by this pull request
@Turnlings Turnlings marked this pull request as draft April 8, 2026 21:51
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR introduces an example migration from per-callsite callbacks to a centralized Blinker-based signal system for broadcasting drone error and connection-status events to the Socket.IO frontend.

Changes:

  • Added radio/app/signals.py defining DroneError and DroneConnectStatus signals with connected Socket.IO emit handlers.
  • Removed the legacy droneConnectStatusCb callback plumbing from utils.py, Drone, and the comPorts/autopilot endpoints.
  • Updated Drone and ArmController to demonstrate emitting errors/status via signals.

Reviewed changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated 7 comments.

Show a summary per file
File Description
radio/app/utils.py Removes legacy droneConnectStatusCb TypedDict + callback from utils.
radio/app/signals.py Adds Blinker signals and Socket.IO-connected handlers for error + connect status.
radio/app/endpoints/comPorts.py Stops passing droneConnectStatusCb into Drone.
radio/app/endpoints/autopilot.py Stops carrying/passing droneConnectStatusCb during reboot reconnect.
radio/app/drone.py Switches connection status and error emission to signals; removes callback field/arg.
radio/app/controllers/armController.py Demonstrates using Drone.error() / DroneError signal on exceptions.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread radio/app/signals.py
Comment on lines +4 to +5
from typing import TypedDict, NotRequired
from app.customTypes import Number
Copy link

Copilot AI Apr 8, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

NotRequired is imported from typing, which will raise ImportError on Python 3.10 (e.g., Ubuntu 22.04 default). Use typing_extensions.NotRequired (and optionally typing_extensions.TypedDict for consistency with the rest of the radio code) or add a version-conditional import fallback.

Copilot uses AI. Check for mistakes.
Comment thread radio/app/signals.py
Comment thread radio/app/signals.py Outdated
Comment on lines 89 to +95
except Exception as e:
self.drone.logger.error(e, exc_info=True)
if self.drone.droneErrorCb:
self.drone.droneErrorCb(str(e))
self.drone.error(str(e))

## Or you can have just have: (TODO: remove)
DroneError.send(str(e))

Copy link

Copilot AI Apr 8, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This exception path will emit the same error twice: self.drone.error(...) already sends DroneError, then DroneError.send(...) is called again. Please remove the duplicate send (and the TODO comment) so the frontend doesn't receive duplicate drone_error events.

Copilot uses AI. Check for mistakes.
Comment thread radio/app/drone.py
Comment thread radio/app/drone.py Outdated
Comment on lines 384 to 387
DroneConnectStatus.send(payload)
except Exception:
self.logger.exception("Connection status callback failed")
return
Copy link

Copilot AI Apr 8, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The log message still refers to a “callback” even though the implementation now uses a signal (DroneConnectStatus). Updating this message will make operational logs easier to understand when diagnosing connection issues.

Copilot uses AI. Check for mistakes.
Comment thread radio/app/drone.py
@Turnlings
Copy link
Copy Markdown
Contributor Author

Ok, looks like the sender thing isnt just recommended but required (even though it worked without??)

Will need to look back tomorrow...

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.

[TASK] Backend publisher/subscriber architecture

2 participants