FazBrowse GitHub Viewer | Trending |
URL:
| Home
Tools: [Download Repo ZIP]   [Original HTTPS Page]

Stop actors when a dispatch update changes its merge identity by Marenz · Pull Request #318 · frequenz-floss/frequenz-dispatch-python · GitHub

Repository navigation

Stop actors when a dispatch update changes its merge identity - #318

Open
Marenz wants to merge 2 commits into
frequenz-floss:v1.x.xfrom
Marenz:fix-identity-change-orphans-actor
Open

Marenz wants to merge 2 commits into
frequenz-floss:v1.x.xfrom
Marenz:fix-identity-change-orphans-actor

Conversation

Marenz commented Oct 22, 2026

Copy link
Copy Markdown
Contributor

Updating a running dispatch could change its merge identity, start a new actor, and leave the old one running.

Remember the identity each dispatch was routed to, stop the old actor when the identity changes (unless another running dispatch still uses it), and drop stale retries.

Fixes #310

Marenz requested a review from a team as a code owner October 22, 2026 13:31
Marenz requested review from stefan-brus-frequenz and removed request for a team October 22, 2026 13:31
github-actions Bot added part:docs Affects the documentation part:tests Affects the unit, integration and performance (benchmarks) tests part:dispatcher Affects the high-level dispatcher interface labels Oct 22, 2026
object.__setattr__(self, "_src", _src)


# pylint: disable=too-many-instance-attributes

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

Not necessarily for this PR, but...

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

Fixed in this PR. I consolidated the new state, so the class is back within the attribute limit and the pylint suppression is gone.

Comment on lines +252 to +259
self._dispatch_identities: dict[DispatchId, DispatchActorId] = {}
"""The identity to which each running dispatch was last routed."""
self._running_dispatches: dict[DispatchId, Dispatch] = {}
"""The latest version of each running dispatch."""
self._dispatch_filter: (
Callable[[Mapping[DispatchId, Dispatch], Dispatch], bool] | None
) = None
self._known_dispatches: Mapping[DispatchId, Dispatch] | None = None

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

There are a few members here that are a dict DispatchId -> Something. Maybe we could have a unified _dispatch_status: dict[DispatchId, DispatchStatus] or similar, where DispatchStatus could be something like identity: DispatchActorId, running: bool.

Maybe with actors too, something like _actors mapping DispatchActorId to something having the actor, channel, and failed dispatches.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

Done. _dispatch_status now maps each dispatch ID to one DispatchStatus with the dispatch and routed identity. _actors now maps each actor identity to one ActorStatus with either the running actor/channel or the failed dispatch. I folded this into the fix commit because these status objects exist to keep the new routing state consistent.

Comment on lines +421 to +423
self._dispatch_identities[dispatch.id] = identity
self._running_dispatches[dispatch.id] = dispatch
self._failed_dispatches.pop(identity, None)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

If we have a class for dispatch status, this can probably be done as one operation in that class, hopefully making manipulating stuff less bug prone (if we forget to update one dict it could be bad).

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

Done. A start or update now replaces one DispatchStatus, and a stop pops one. The dispatch and its identity can no longer drift between separate maps.

Comment on lines -64 to 73
running_dispatch_list = [
existing_dispatch
for existing_dispatch in dispatches.values()
if (
self.identity(existing_dispatch) == self.identity(dispatch)
and existing_dispatch.id != dispatch.id
)
]

other_dispatches_running = any(
running_dispatch.started_at(now)
for running_dispatch in running_dispatch_list
running_dispatch_list = _other_running_dispatches(
dispatches,
dispatch.id,
self.identity(dispatch),
self.identity,
now=now,
)
other_dispatches_running = bool(running_dispatch_list)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

Is this really necessary in MergeByType? It uses type and dry_run as identity, both immutable AFAIK. I think it is only needed in MergeByTypeTarget because it adds target, which is mutable (an update can change it).

Maybe we can keep it at the top just in case anyway, in case we support updating dry_run or type, although I think it is very unlikely because it doesn't make a lot of sense (maybe dry_run, but it could still be dangerous, and I think we made it immutable because we found issues with allowing mutations for it).

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

The identity comparison is still needed, but not for an identity mutation. The receiver filters only by type, so same-type dry-run and real dispatches can both reach this filter and must not suppress each other's stop events. I kept the check, added a short comment, and preserved the existing started_at(now) timing.

Comment thread RELEASE_NOTES.md

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

Not a biggie but it would be better to split the release notes resets from the update.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

Done. The v1.0.4 reset is now its own first commit, and the new bug-fix entry stays with the fix commit.

The v1.0.4 notes were still present after the release.
Restore the empty template before adding new entries.

Signed-off-by: Mathias L. Baumann <mathias.baumann@frequenz.com>
Remember each dispatch's routed identity in one status record. If it changes,
stop the old actor unless another running dispatch still uses it.

Keep failed starts with actor state so retries cannot drift from routing state.

Signed-off-by: Mathias L. Baumann <mathias.baumann@frequenz.com>
Marenz force-pushed the fix-identity-change-orphans-actor branch from 6573546 to 07c983c Compare October 23, 2026 12:19

This branch has not been deployed

No deployments
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

part:dispatcher Affects the high-level dispatcher interface part:docs Affects the documentation part:tests Affects the unit, integration and performance (benchmarks) tests

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Actor is never stopped when a dispatch update changes its merge identity

2 participants


Back | FazBrowse Home | New Git URL