Skip to content

Conversation

masenf
Copy link
Collaborator

@masenf masenf commented Oct 17, 2025

When final=None, the frontend does not update the event_processing flag.

When `final=None`, the frontend does not update the `event_processing` flag.
@linear
Copy link

linear bot commented Oct 17, 2025

@codspeed-hq
Copy link

codspeed-hq bot commented Oct 17, 2025

CodSpeed Performance Report

Merging #5898 will create unknown performance changes

Comparing masenf/background-never-resets-event-processing (2581549) with main (e53b65d)

Summary

⚠️ No benchmarks were detected in both the base of the PR and the PR.
Please ensure that your benchmarks are correctly instrumented with CodSpeed.

Check out the benchmarks creation guide

⏩ 8 skipped1

Footnotes

  1. 8 benchmarks were skipped, so the baseline results were used instead. If they were deleted from the codebase, click here and archive them to remove them from the performance reports.

Copy link
Contributor

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

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

Greptile Overview

Summary

Changed how background event handlers and background state modifications communicate with the frontend by setting final=None instead of final=True. This prevents the frontend from updating the event_processing flag when background tasks emit state updates, allowing the event queue to continue processing without being blocked by background operations.

Key changes:

  • Modified StateUpdate.final from bool to bool | None to support a tri-state value
  • Background event handlers now return final=None instead of final=True in reflex/state.py:1782
  • Added background parameter to App.modify_state() method to distinguish background modifications
  • StateProxy now passes background=True when calling modify_state() for background operations
  • Frontend JavaScript now checks if (update.final !== null) before updating event_processing flag

Impact:
This change ensures background tasks can update state without interfering with the frontend's event processing queue management, preventing race conditions where background updates would incorrectly signal completion of foreground events.

Confidence Score: 5/5

  • This PR is safe to merge with minimal risk
  • The changes are well-designed and logically sound. The tri-state approach (final=True|False|None) cleanly separates background operations from foreground event processing. The JavaScript null check is defensive and won't break existing behavior. All changes are coordinated across the frontend-backend boundary correctly.
  • No files require special attention

Important Files Changed

File Analysis

Filename Score Overview
reflex/.templates/web/utils/state.js 5/5 Added null check for update.final before updating event_processing flag, preventing unintended flag updates from background tasks
reflex/state.py 5/5 Changed StateUpdate.final type to `bool
reflex/app.py 5/5 Added background parameter to modify_state() method to distinguish background modifications and set final=None for background updates
reflex/istate/proxy.py 5/5 Updated StateProxy to pass background=True when calling modify_state(), ensuring background state modifications are properly flagged

Sequence Diagram

sequenceDiagram
    participant Frontend as Frontend (state.js)
    participant Backend as Backend (App)
    participant State as BaseState
    participant Proxy as StateProxy
    
    Note over Frontend,Proxy: Background Event Handler Flow
    State->>State: Process background event handler
    State->>State: Set final=None (not True)
    State->>Backend: Return StateUpdate(delta, final=None)
    Backend->>Frontend: Emit update with final=None
    Frontend->>Frontend: Check if update.final !== null
    Frontend->>Frontend: Skip event_processing flag update
    Note over Frontend: event_processing remains unchanged
    
    Note over Frontend,Proxy: Background State Modification via Proxy
    Proxy->>Backend: modify_state(token, background=True)
    Backend->>Backend: Acquire state lock
    Backend->>Proxy: Yield mutable state
    Proxy->>State: Modify state
    Backend->>Backend: Get delta from state
    Backend->>Backend: Set final=None (background=True)
    Backend->>Frontend: Emit StateUpdate(delta, final=None)
    Frontend->>Frontend: Check if update.final !== null
    Frontend->>Frontend: Skip event_processing flag update
    
    Note over Frontend,Proxy: Regular Event Handler Flow
    State->>State: Process regular event handler
    State->>State: Set final=True
    State->>Backend: Return StateUpdate(delta, final=True)
    Backend->>Frontend: Emit update with final=True
    Frontend->>Frontend: Check if update.final !== null
    Frontend->>Frontend: Set event_processing = false
Loading

4 files reviewed, no comments

Edit Code Review Agent Settings | Greptile

@adhami3310 adhami3310 merged commit 0f8c19d into main Oct 23, 2025
46 of 47 checks passed
@adhami3310 adhami3310 deleted the masenf/background-never-resets-event-processing branch October 23, 2025 20:27
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