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

redis hash for StateManagerRedis #4459

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

Conversation

benedikt-bartscher
Copy link
Contributor

@benedikt-bartscher benedikt-bartscher commented Dec 1, 2024

Drastically reduces the amount of redis calls for apps with many states
Keeps all states of a session in one redis hashmap instead of separate redis keys

@benedikt-bartscher benedikt-bartscher changed the title Redis hashset redis hash for StateManagerRedis Dec 1, 2024
@benedikt-bartscher benedikt-bartscher marked this pull request as ready for review December 3, 2024 01:44
@benedikt-bartscher
Copy link
Contributor Author

ci failure is the typical dynamic routes flakyness

benedikt-bartscher and others added 9 commits December 9, 2024 12:18
remove oxbow code now that REDIS_URL must be a real redis url
Continue to support redis < 7.2

Instead of updating individual substate expiration, in older versions of redis
any update to any substate will cause the entire state expiration to be
refreshed, which is better than not supporting older redis versions.
redis-py 5.1.0 adds support for the .hexpire() command
@masenf
Copy link
Collaborator

masenf commented Dec 12, 2024

@benedikt-bartscher i really like this one 👍

@benedikt-bartscher
Copy link
Contributor Author

@masenf thanks for the feedback and compability improvements you have pushed. I really appreciate it. We are already using this since some weeks and did not experience any issues. Will update our fork to the latest changes and keep you posted if everything still works.

@benedikt-bartscher
Copy link
Contributor Author

No issues so far, thanks again @masenf!
Going to fix the conflicts quickly

@benedikt-bartscher
Copy link
Contributor Author

FAILED tests/units/test_state.py::test_state_manager_lock_warning_threshold_contend - AssertionError: assert 1 == 7
the new test seems to fail on my machine with REDIS_URL set

Now that all substates are persisted together, there is only 1 warning message
expected, not 7
@masenf
Copy link
Collaborator

masenf commented Dec 13, 2024

the new test seems to fail on my machine with REDIS_URL set

pushed a fix; we only need to expect one warning message now, since we're only writing to redis once per event 😎

@masenf
Copy link
Collaborator

masenf commented Dec 13, 2024

@benedikt-bartscher have you profiled this? i notice that it's making fewer redis calls, but the state updates on reflex-web when bumping the counter on /docs/getting-started/introduction are taking ~0.04s whereas with main they only take ~0.02s

Not clear why it's taking twice as long to get/set the state with the new approach.

@benedikt-bartscher
Copy link
Contributor Author

@benedikt-bartscher have you profiled this? i notice that it's making fewer redis calls, but the state updates on reflex-web when bumping the counter on /docs/getting-started/introduction are taking ~0.04s whereas with main they only take ~0.02s

Not clear why it's taking twice as long to get/set the state with the new approach.

@masenf i have not profiled it yet. Only checked the amount of redis calls. I wonder if the impact is from the actual redis calls or the computation of which states need to be fetched.

If this is due to redis hash, we can migrate back to normal redis keys using Pipelines to reduce the amount of requests.

Will take a look on this over the weekend.

@benedikt-bartscher
Copy link
Contributor Author

@masenf I did some basic benchmarking with a redis server running on localhost (which is a bit unfair). Most state manager operations with this branch took longer than on main. I pushed the benchmark if you want to try or investigate.

@benedikt-bartscher
Copy link
Contributor Author

If this is due to redis hash, we can migrate back to normal redis keys using Pipelines to reduce the amount of requests.

It is not.

Set of full state names that may need to be fetched to recalc computed vars.
"""
fetch_substates = cls._potentially_dirty_substates()
for substate_cls in cls.get_substates():
Copy link
Contributor Author

Choose a reason for hiding this comment

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

this is not optimal, we only need to loop over the potentially dirty substates

@benedikt-bartscher
Copy link
Contributor Author

but the state updates on reflex-web when bumping the counter on /docs/getting-started/introduction are taking ~0.04s whereas with main they only take ~0.02s

How did you measure this? Just watch the ws timestamps?
I pushed some minor performance improvements.

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