Skip to content
This repository was archived by the owner on Oct 22, 2025. It is now read-only.

Conversation

@NathanFlurry
Copy link
Member

No description provided.

@claude
Copy link

claude bot commented Sep 12, 2025

Claude finished @NathanFlurry's task —— View job


Code Review in Progress

Reviewing the changes in this PR focusing on code quality, potential bugs, performance, security, and test coverage.

Todo List

  • Read and analyze the modified file packages/rivetkit/src/actor/instance.ts
  • Examine the surrounding code context
  • Evaluate code quality and best practices
  • Check for potential bugs or issues
  • Review performance considerations
  • Assess security concerns
  • Evaluate test coverage needs
  • Provide comprehensive feedback

Code Review Feedback

The changes look good! This is a small but important bug fix that addresses a specific issue with the onStateChange callback being triggered for non-state mutations.

What the Fix Does

The change adds a guard clause to the onChange proxy callback in the #setPersist method (lines 627-629):

if (path !== "state" && !path.startsWith("state.")) {
    return;
}

This ensures that onStateChange is only called when actual state properties are modified, not when other properties in the PersistedActor object (like connections, scheduledEvents, input, etc.) are changed.

Code Quality ✅ Good

  • Clear Intent: The fix directly addresses the issue described in the PR title
  • Minimal Change: Only 4 lines added with surgical precision
  • Consistent Style: Follows existing code patterns and formatting
  • Proper Guard: Early return pattern prevents unnecessary processing

Potential Bugs ✅ None Identified

  • The path filtering logic is correct for the PersistedActor structure
  • The check handles both direct "state" changes and nested "state.property" changes
  • No edge cases appear to be missed

Performance Considerations ✅ Positive Impact

  • Reduced Overhead: Eliminates unnecessary onStateChange callback invocations
  • Early Exit: The guard clause prevents expensive operations (CBOR serialization validation, inspector events, callback execution) for non-state changes
  • String Operations: The path checks are simple string operations with minimal cost

Security Concerns ✅ No Issues

  • The change is purely defensive and doesn't introduce any security risks
  • Path validation is straightforward string comparison
  • No external input is involved in this logic

Test Coverage Considerations ⚠️ Needs Attention

While the change is simple and correct, consider adding tests to verify:

  1. Positive Case: onStateChange is called when state or state.property changes
  2. Negative Cases: onStateChange is NOT called when:
    • connections array is modified
    • scheduledEvents array is modified
    • input property changes
    • hasInitiated property changes

Example test scenarios:

// Should trigger onStateChange
instance.state.someProperty = "new value";

// Should NOT trigger onStateChange  
instance.#persist.connections.push(newConnection);
instance.#persist.scheduledEvents.push(newEvent);
instance.#persist.hasInitiated = true;

Minor Suggestions

  1. Documentation: Consider adding a brief comment explaining why this guard exists:

    // Only trigger state change notifications for actual state mutations
    if (path !== "state" && !path.startsWith("state.")) {
        return;
    }
  2. Constants: For consistency, you could define the path prefix as a constant, but this is probably overkill for such a simple check.

Overall Assessment ⭐⭐⭐⭐⭐

This is a well-executed bug fix that:

  • Solves the exact problem described
  • Has positive performance implications
  • Maintains code quality standards
  • Introduces no new risks

Recommendation: Approve with consideration for adding tests to prevent regression.


Copy link
Member Author

NathanFlurry commented Sep 12, 2025

Warning

This pull request is not mergeable via GitHub because a downstack PR is open. Once all requirements are satisfied, merge this PR as a stack on Graphite.
Learn more


How to use the Graphite Merge Queue

Add either label to this PR to merge it via the merge queue:

  • merge queue - adds this PR to the back of the merge queue
  • hotfix - for urgent hot fixes, skip the queue and merge this PR next

You must have a Graphite account in order to use the merge queue. Sign up using this link.

An organization admin has enabled the Graphite Merge Queue in this repository.

Please do not merge from GitHub as this will restart CI on PRs being processed by the merge queue.

This stack of pull requests is managed by Graphite. Learn more about stacking.

@graphite-app
Copy link

graphite-app bot commented Sep 12, 2025

Merge activity

  • Sep 12, 5:08 PM UTC: NathanFlurry added this pull request to the Graphite merge queue.
  • Sep 12, 5:09 PM UTC: CI is running for this pull request on a draft pull request (#1211) due to your merge queue CI optimization settings.
  • Sep 12, 5:09 PM UTC: Merged by the Graphite merge queue via draft PR: #1211.

graphite-app bot pushed a commit that referenced this pull request Sep 12, 2025
@graphite-app graphite-app bot closed this Sep 12, 2025
@graphite-app graphite-app bot deleted the 09-12-fix_core_fix_notifying_onstatechange_for_non-state_mutations_to_persisted_state branch September 12, 2025 17:09
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants