async def process(
    app: App, event: Event, sid: str, headers: dict, client_ip: str
) -> AsyncIterator[StateUpdate]:
    """Process an event.

    Args:
        app: The app to process the event for.
        event: The event to process.
        sid: The Socket.IO session id.
        headers: The client headers.
        client_ip: The client_ip.

    Raises:
        Exception: If a reflex specific error occurs during processing the event.

    Yields:
        The state updates after processing the event.
    """
    from reflex.utils import telemetry

    try:
        # Add request data to the state.
        router_data = event.router_data
        router_data.update(
            {
                constants.RouteVar.QUERY: format.format_query_params(event.router_data),
                constants.RouteVar.CLIENT_TOKEN: event.token,
                constants.RouteVar.SESSION_ID: sid,
                constants.RouteVar.HEADERS: headers,
                constants.RouteVar.CLIENT_IP: client_ip,
            }
        )
        # Get the state for the session exclusively.
        async with app.state_manager.modify_state(event.substate_token) as state:
            # When this is a brand new instance of the state, signal the
            # frontend to reload before processing it.
            if (
                not state.router_data
                and event.name != get_hydrate_event(state)
                and app.event_namespace is not None
            ):
                await asyncio.create_task(
                    app.event_namespace.emit(
                        "reload",
                        data=event,
                        to=sid,
                    )
                )
                return
            # re-assign only when the value is different
            if state.router_data != router_data:
                # assignment will recurse into substates and force recalculation of
                # dependent ComputedVar (dynamic route variables)
                state.router_data = router_data
                state.router = RouterData(router_data)

            # Preprocess the event.
            update = await app._preprocess(state, event)

            # If there was an update, yield it.
            if update is not None:
                yield update

            # Only process the event if there is no update.
            else:
                if app._process_background(state, event) is not None:
                    # `final=True` allows the frontend send more events immediately.
                    yield StateUpdate(final=True)
                else:
                    # Process the event synchronously.
                    async for update in state._process(event):
                        # Postprocess the event.
                        update = await app._postprocess(state, event, update)

                        # Yield the update.
                        yield update
    except Exception as ex:
        telemetry.send_error(ex, context="backend")

        app.backend_exception_handler(ex)
        raise
Process an event.

    Args:
        app: The app to process the event for.
        event: The event to process.
        sid: The Socket.IO session id.
        headers: The client headers.
        client_ip: The client_ip.

    Raises:
        Exception: If a reflex specific error occurs during processing the event.

    Yields:
        The state updates after processing the event.
    
reflex/app.py