Skip to content

refactor(pb): fix actor overdue alarm handling#4770

Merged
NathanFlurry merged 1 commit intomainfrom
04-24-refactor_pb_fix_actor_overdue_alarm_handling
Apr 27, 2026
Merged

refactor(pb): fix actor overdue alarm handling#4770
NathanFlurry merged 1 commit intomainfrom
04-24-refactor_pb_fix_actor_overdue_alarm_handling

Conversation

@MasterPtato
Copy link
Copy Markdown
Contributor

Description

Please include a summary of the changes and the related issue. Please also include relevant motivation and context.

Type of change

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • This change requires a documentation update

How Has This Been Tested?

Please describe the tests that you ran to verify your changes.

Checklist:

  • My code follows the style guidelines of this project
  • I have performed a self-review of my code
  • I have commented my code, particularly in hard-to-understand areas
  • I have made corresponding changes to the documentation
  • My changes generate no new warnings
  • I have added tests that prove my fix is effective or that my feature works
  • New and existing unit tests pass locally with my changes

@claude
Copy link
Copy Markdown

claude Bot commented Apr 24, 2026

PR Review: Overdue Alarm Check Refactor in Pegboard Actor2

Summary

This PR refactors the overdue alarm check in handle_stopped within the Pegboard actor2 lifecycle workflow. The alarm check was previously duplicated inside the Decision::Sleep arm, replicating the full allocate → start → send_outbound path already present in Decision::Reallocate. The refactor lifts that check to before the stopped_res match, converting Decision::Sleep to Decision::Reallocate when the alarm is overdue and sharing the existing allocation path. Net result: -29 lines, no duplication, cleaner intent.


Correctness

Behavior preserved in happy path. When an alarm is overdue at Decision::Sleep time, the new code upgrades the decision to Decision::Reallocate, which handles allocation via the same path as the existing Reallocate arm. The actor lifecycle effect is identical.

Alarm guard is correctly scoped. if let (Decision::Sleep, Some(alarm_ts)) = (&decision, state.alarm_ts) limits the override to the only relevant decision — other decisions (Reallocate, Backoff, Destroy) don't need alarm inspection.

alarm_ts cleared on overdue. state.alarm_ts = None is set when the overdue path is taken, matching the deleted code.

Subtle change worth confirming: In the old code, the overdue-alarm branch inside Decision::Sleep did not call SetSleepingInput. In the new code, the post-match block runs unconditionally:

match state.transition {
    Transition::Sleeping | Transition::Reallocating { .. } => {
        ctx.activity(SetSleepingInput {}).await?;
    }
    _ => {}
}

When the overdue-alarm path results in a failed allocation (setting Transition::Reallocating), SetSleepingInput is now called — it wasn't before. This is likely a bug fix (the old code could leave an actor in Transition::Reallocating without marking it as sleeping in UDB), but it's worth confirming that this is intentional.


Code Quality

  • Deduplication is correct. Sharing the Decision::Reallocate path instead of repeating the allocation logic is the right design.
  • Readability improved. The alarm check is visually separated before the match, making the decision sequence easy to read top-to-bottom: initial decision → alarm override → act on decision.
  • Enum exhaustiveness. All four Decision variants are explicitly handled in stopped_res. No _ => fall-through on the enum match. Consistent with CLAUDE.md conventions.
  • Pre-existing concern (not introduced here). The outer match state.transition at the start of handle_stopped uses _ => to cover several Transition variants (Allocating, Starting, Running, Reallocating, StopIntent). A future Transition variant could be silently swallowed there.
  • let mut decision is required since the alarm check may reassign it. Idiomatic.

Performance

No concerns. The GetTsInput activity call is still only invoked when decision == Decision::Sleep && state.alarm_ts.is_some(). No additional activities are invoked on the common path.


Security

No concerns. This is a pure internal lifecycle state machine refactor with no trust boundary impact.


Test Coverage

No tests were added or updated. The changed path (actor stops while in sleep-intent with an overdue alarm) requires:

  1. An actor in SleepIntent { rewake_after_stop: false } or equivalent sleep decision
  2. alarm_ts set
  3. Current time at or past alarm_ts at stop time

An integration test covering this scenario would prevent future regressions, especially since the old code's duplication was the kind of thing that could silently diverge.


Verdict

Approve with minor note. The refactor is correct and clearly improves the code. One thing to confirm: the new code now calls SetSleepingInput when the overdue-alarm path ends in Transition::Reallocating (failed allocation), where the old code did not. If this is an intentional bug fix, a brief comment explaining why would help future readers. If unintentional, it should be investigated before merging.

@MasterPtato MasterPtato force-pushed the 04-24-refactor_pb_fix_actor_overdue_alarm_handling branch from 6851547 to 3cfcb16 Compare April 25, 2026 01:07
@MasterPtato MasterPtato force-pushed the 04-23-fix_update_railway_docs_to_include_graceful_shutdown branch from df97819 to 3ff43a4 Compare April 25, 2026 01:07
@MasterPtato MasterPtato force-pushed the 04-24-refactor_pb_fix_actor_overdue_alarm_handling branch from 3cfcb16 to 31253f7 Compare April 25, 2026 01:14
@MasterPtato MasterPtato force-pushed the 04-23-fix_update_railway_docs_to_include_graceful_shutdown branch from 3ff43a4 to 0a19554 Compare April 25, 2026 01:14
@MasterPtato MasterPtato force-pushed the 04-23-fix_update_railway_docs_to_include_graceful_shutdown branch from 0a19554 to ac23ccc Compare April 27, 2026 18:04
@MasterPtato MasterPtato force-pushed the 04-24-refactor_pb_fix_actor_overdue_alarm_handling branch from 31253f7 to 1b63227 Compare April 27, 2026 18:04
Base automatically changed from 04-23-fix_update_railway_docs_to_include_graceful_shutdown to main April 27, 2026 20:38
@NathanFlurry NathanFlurry merged commit 1b63227 into main Apr 27, 2026
11 of 43 checks passed
@NathanFlurry NathanFlurry deleted the 04-24-refactor_pb_fix_actor_overdue_alarm_handling branch April 27, 2026 20:38
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.

2 participants