Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Connection state #2671

Draft
wants to merge 11 commits into
base: main
Choose a base branch
from

Conversation

benedikt-bartscher
Copy link
Contributor

@benedikt-bartscher benedikt-bartscher commented Feb 20, 2024

import asyncio
import datetime

import reflex as rx
from reflex.state import SessionStatusEnum


class State(rx.State):
    count: int = 0
    first_event: datetime.datetime = datetime.datetime.now()
    # events: list[tuple[SessionStatusEnum, datetime.datetime]] = []

    # def on_load(self) -> None:
    #     last_status = self.events[-1][0] if self.events else None
    #
    #     if self.status == last_status:
    #         return
    #
    #     new_event = (self.status, datetime.datetime.now())
    #     self.events.append(new_event)

    def increment(self) -> None:
        self.count += 1

    @rx.var
    def last_event(self) -> datetime.datetime:
        return self._session_status.last_event

    @rx.var
    def status(self) -> SessionStatusEnum:
        return self._session_status.status

    @rx.background
    async def background(self) -> None:
        while True:
            await asyncio.sleep(1)
            async with self:
                if self.status == SessionStatusEnum.DISCONNECTED:
                    print("Session disconnected")
                    break
                self.count += 1
            print(f"background loop: {self.count}")


def index() -> rx.Component:
    return rx.fragment(
        rx.button("Increment", on_click=State.increment),  # pyright: ignore[reportUnknownMemberType]
        rx.button("Start Background", on_click=State.background),  # pyright: ignore[reportUnknownMemberType]
        rx.text(State.count),
        rx.text(f"session_id: {State.router.session.session_id}"),
        rx.text(f"client_token: {State.router.session.client_token}"),
        rx.text(f"last_event: {State.last_event}"),
        rx.text(f"first_event: {State.first_event}"),
        rx.text(f"status: {State.status}"),
        # rx.text("events:"),
        # rx.foreach(State.events, lambda event: rx.text(f"{event[0]}: {event[1]}")),
    )


app = rx.App()
app.add_page(
    index,
    # on_load=State.on_load,
)

@Lendemor
Copy link
Collaborator

I missed that PR before.

I kinda like the idea of having a SessionStatus field.

Do you think you could later update this PR to use the change from #3388 once they are merged ?

@benedikt-bartscher
Copy link
Contributor Author

@Lendemor no worries, it wasn't really finished yet. I will rebase once your PR is merged.

@Lendemor
Copy link
Collaborator

#3388 PR is merged.

Feel free to ping me when this one is ready for review.

@benedikt-bartscher
Copy link
Contributor Author

@Lendemor I rebased it and added a small use example in the issue description.
The functionality is ready for review, but I'll need to adjust some tests which do not expect the new session state to be there (with #2429 fewer tests would need to be adjusted).

@Lendemor
Copy link
Collaborator

@benedikt-bartscher Got it, I'll review whenever the PR is marked as ready 👍

@benedikt-bartscher benedikt-bartscher marked this pull request as ready for review June 24, 2024 18:14
Copy link
Collaborator

@masenf masenf left a comment

Choose a reason for hiding this comment

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

i started looking at the test changes, but i think if we just avoid sending these new fields in the delta then the tests can stay the way they are.

reflex/app.py Outdated Show resolved Hide resolved
@benedikt-bartscher benedikt-bartscher changed the title Draft: Connection state Connection state Jun 27, 2024
@benedikt-bartscher
Copy link
Contributor Author

Anything else missing here?

Copy link
Collaborator

@masenf masenf left a comment

Choose a reason for hiding this comment

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

hitting a couple of issues with this

  1. all states seem to share the same _session_status; i think this needs to be declared as a pydantic.PrivateAttr so each instance gets its own copy
  2. the RECONNECTED state does not seem to "stick". it shows up once when the initial reconnection happens, but then immediately changes to CONNECTED again, so detecting the reconnected state is not really possible if there is an on_load or some other event processed before the handler that is supposed to check the status.

We might need some integration tests for this feature.

Copy link
Collaborator

@masenf masenf left a comment

Choose a reason for hiding this comment

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

Needs a test case and the above issues addressed (accidentally clicked approve earlier)

@benedikt-bartscher
Copy link
Contributor Author

Thanks for looking into this!

  1. is fixed in 39b5658
  2. yes, I noticed this as well. I will drop reconnected for now

@Lendemor
Copy link
Collaborator

Marking this as draft until ready for review.

@Lendemor Lendemor marked this pull request as draft October 25, 2024 18:02
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