Skip to content

fix(HitTest): don't hang waitUsableRectUpdate when graph stabilizes via processQueue drain#325

Merged
draedful merged 4 commits into
mainfrom
fix_hittest
Jul 15, 2026
Merged

fix(HitTest): don't hang waitUsableRectUpdate when graph stabilizes via processQueue drain#325
draedful merged 4 commits into
mainfrom
fix_hittest

Conversation

@Antamansid

@Antamansid Antamansid commented Jul 15, 2026

Copy link
Copy Markdown
Collaborator

Problem

In its deferred branch (when the graph is still isUnstable at call time), waitUsableRectUpdate subscribed its stability check to only two signals — $usableRect and $pendingEntitiesUpdate. But the isUnstable getter depends on three conditions: a zero $usableRect, $pendingEntitiesUpdate, and the hitbox processing queue state (processQueue.isScheduled() || queue.size > 0).
The queue is not a signal, so it never triggers the subscription.

This creates a dead spot: the graph can stabilize purely by draining the queue (a re-entrant second processQueue run), while $usableRect and $pendingEntitiesUpdate already hold their final values (updateUsableRect early-returns on an unchanged rect, pending is already false). Neither signal notifies, so the callback is never invoked and waitUsableRectUpdate hangs forever.

Summary by Sourcery

Ensure HitTest usable-rect waiters resolve when stability is reached via processing-queue drainage rather than signal updates.

Bug Fixes:

  • Fix waitUsableRectUpdate hanging when the hit-test graph stabilizes only through a re-entrant processQueue drain that does not change $usableRect or $pendingEntitiesUpdate.

Tests:

  • Add regression test covering re-entrant two-batch processQueue runs to verify waitUsableRectUpdate resolves when stability is achieved via queue draining.

@Antamansid
Antamansid requested a review from draedful as a code owner July 15, 2026 15:07
@sourcery-ai

sourcery-ai Bot commented Jul 15, 2026

Copy link
Copy Markdown

Reviewer's Guide

Ensures HitTest.waitUsableRectUpdate no longer hangs when the graph stabilizes via a re-entrant processQueue drain by adding a regression test and wiring the deferred wait logic to also re-check stability on the HitTest "update" event, in addition to the existing signal subscriptions.

File-Level Changes

Change Details Files
Add regression coverage for re-entrant processQueue behavior that stabilizes the graph without further signal changes.
  • Introduce triggerReentrantProcessQueue helper that simulates a two-batch, re-entrant processQueue run where a second hitbox update is scheduled during the first batch and the graph stabilizes purely via queue draining.
  • Add a new test ensuring waitUsableRectUpdate resolves when stability is achieved through the re-entrant queue drain, validating that callbacks no longer hang in this scenario.
src/services/HitTest.test.ts
Fix deferred waitUsableRectUpdate to observe non-signal-driven stabilization by subscribing its stability check to the HitTest "update" event.
  • Refactor the deferred branch of waitUsableRectUpdate to store the stability check function in a mutable variable so it can be shared between signal subscriptions and event listeners.
  • Extend cleanup logic to unsubscribe the check handler from the "update" event along with the existing signal unsubscriptions.
  • Subscribe the stability check to the HitTest "update" event so that isUnstable is re-evaluated after every processQueue run, covering cases where the queue draining alone stabilizes the graph without changing $usableRect or $pendingEntitiesUpdate.
src/services/HitTest.ts

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Hey - I've left some high level feedback:

  • In waitUsableRectUpdate, you can avoid the check noop initialization and reassignment by defining check before cleanup and closing over it, which would simplify the control flow and make the subscription/unsubscription logic easier to follow.
  • The new triggerReentrantProcessQueue test helper relies on casting to unknown as HitBox with partially implemented objects; consider extracting a small factory or shared helper for these stub hitboxes to reduce duplication and make the intent of the fake implementation clearer.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- In `waitUsableRectUpdate`, you can avoid the `check` noop initialization and reassignment by defining `check` before `cleanup` and closing over it, which would simplify the control flow and make the subscription/unsubscription logic easier to follow.
- The new `triggerReentrantProcessQueue` test helper relies on casting to `unknown as HitBox` with partially implemented objects; consider extracting a small factory or shared helper for these stub hitboxes to reduce duplication and make the intent of the fake implementation clearer.

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

@gravity-ui-bot

Copy link
Copy Markdown
Contributor

Preview is ready.

@draedful
draedful merged commit 9294f05 into main Jul 15, 2026
6 checks passed
@draedful
draedful deleted the fix_hittest branch July 15, 2026 16:13
@gravity-ui gravity-ui Bot mentioned this pull request Jul 15, 2026
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.

3 participants