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

Provide app.storage.tab #2837

Merged
merged 7 commits into from
Apr 8, 2024
Merged

Provide app.storage.tab #2837

merged 7 commits into from
Apr 8, 2024

Conversation

rodja
Copy link
Member

@rodja rodja commented Apr 6, 2024

This pull request picks up on the idea from #2820 (comment) and other discussion around this topic to implement app.storage.tab: a volatile storage which keeps a state dictionary as long as the browser tab lives. That means the data survives page reloads and switching urls.

It is implemented by storing the dictionary in the memory of the server. To decide which dictionary needs to be accessed the pull request introduces a client.tab_id which is automatically set when doing the websocket handshake.

ToDos

  • When to delete the storage dicts? A tab could revisit the page even after a few days...
  • add tests
  • add demo

@Alyxion
Copy link
Contributor

Alyxion commented Apr 6, 2024

  • When to delete the storage dicts? A tab could revisit the page even after a few days...

I am one who always closes all browser tabs asap but I know many people who have like 50+ tabs over weeks who even have to scroll horizontally and just still identify the tab by the fav icon and first letter.

I think we need to differentiate here between important, un-recoverable, compact and most importantly serializable data... like a long text someone typed and it would really hurt if it were lost... or the user's avatar we just cached in storage.tab so we don't have to pull it from the database every time.

If one could flag such data as "important" then we could transfer it in a configurable intervals from the server to the client and store it next to "__nicegui_tab_id" in the local storage.

And when the connection was completely broken (PC shutdown, browser closed etc.) and is then re-established we could just send all this data along with the handshake back to the server and then the server can decide if it can be recovered.
Could become problematic of course between version changes of the server and such situations but thats the same for cookies already.

@rodja
Copy link
Member Author

rodja commented Apr 6, 2024

I think we need to differentiate here between important, un-recoverable, compact and most importantly serializable data

I would rather like to not do that. Maybe we can leave that it in the hands of the user? I suggest we do:

  1. keep the data only in memory (eg. accept full loss if server restarts) -- that way we can store any Python objects just like app.storage.client from Provide app.storage.client as a location to store volatile data which only matters for the current connection #2820.
  2. remove data which is not accessed for over a month (this is also the default cookie lifetime for app.storage.browser); may be related to Auto-clean stored json files created by `app.storage` #991
  3. make the data lifetime configurable via parameter in ui.run; may be related to Allow setting max_age/https_only of Session Middleware #1448

Maybe later we can add a feature that saves all serializable fields to a file in regular intervals -- and load this on server startup.

@rodja rodja added this to the 1.4.21 milestone Apr 7, 2024
@rodja rodja marked this pull request as ready for review April 7, 2024 04:17
@rodja
Copy link
Member Author

rodja commented Apr 7, 2024

I created #2841 as a feature request for persistence across server restarts.

@Alyxion
Copy link
Contributor

Alyxion commented Apr 7, 2024

Looks great. Two remarks though:

  • If one would store his data like so app.storage.tab['User'] = {'user_id':..., 'last_message'.'''} and then change the values within subdict an interaction will never reduce the timeout. If someone is not aware of this then the session will timeout even though he interacts with the page. May be an "active tab" should update the timeout automatically instead.
  • The time delta of 30 days is mentioned nowhere in the documentation. (also seems a bit much as default buts thats another story)

Other than that the Exceptions triggered by auto-index and missing client connection in the unit tests are not yet covered, don't know if you guys aim here for high coverage. See here.

@rodja
Copy link
Member Author

rodja commented Apr 8, 2024

If one would store his data like so app.storage.tab['User'] = {'user_id':..., 'last_message'.'''} and then change the values within subdict an interaction will never reduce the timeout.

That should work. ObservableDict supports hierarchical observation 😎

@falkoschindler falkoschindler merged commit 0c5896e into main Apr 8, 2024
6 checks passed
@falkoschindler falkoschindler deleted the tab-storage branch April 8, 2024 09:16
@falkoschindler
Copy link
Contributor

@rodja There seems to be an issue with this PR: #2866

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants