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

Serverside-persisted user preferences #1021

Closed

Conversation

brontolosone
Copy link
Contributor

@brontolosone brontolosone commented Sep 4, 2024

Towards getodk/central#689
Supersedes #1018
Related: getodk/central-backend#1184

This introduces persistent user preferences as per getodk/central#689.
The backend (see getodk/central-backend#1184) simply stores the json-serialized user-associated preferences object; the preferences themselves are opaque to the backend.

The semantics of the preferences object are completely up to the frontend.

Implemented preferences:

  • Project listing sort order
  • Per-project deleted forms hiding (trash collapsed/expanded state)

Todo:

  • Fixup the tests
  • Potentially: synchronize across instantiations in the same browser (across tabs). It's quite simple, using BroadcastChannel, but is it desirable? (K:No, W: No)
  • Potentially: synchronize across sessions, but that requires some serverside push, or clientside polling. (K:No, W: No)

Design choices made

The preferences object

  • No formal schema is enforced. The preferences object is schemaless, in other words, it's ad-hoc defined in the frontend usage sites. There is no registry of currently in use configuration keys and the typing of their values. This means, for instance, that orphaned preferences would ping back and forth forever. It also means that the frontend could crash on unexpected values left behind by an earlier version of it. Potential solution: Model the preferences object, eg using jsonschema.
  • There is no schema, and thus no schema versioning with which a frontend could recognize that it's not capable of working with the received preferences object. Potential solution: Model the preferences object, eg using jsonschema, and add a version identifier to annotate incompatible schema changes (by hand, when we think an incompatibility arises). The frontend would then start with a clean slate.
  • There are no provisions for any "frontend app" identifier. Theoretically, one could see the getodk/central-frontend as just one of potentially many frontends, potentially used concurrently by the same user. The preferences schemas (implicit or not) of a multitude of frontends are likely not compatible with one another. Potential solution: The backend stores the preferences object under an app identifier key; and this key will be read from the backend API URLs. Frontends would construct URLs with their frontend identifier (eg org.getodk.central-frontend) in it, so that the backend scopes operations to the json under that key.

We could fold "frontend app identifier" and "schema version" in one, and use app identifier keys such as org.getodk.central-frontend.1 where we bump the last number for every incompatible schema change, in fact treating them as different frontends, which in fact they are.

Considerations on this: K: let's think about it more

Concurrent sessions

  • The preferences are retrieved once by the frontend, after which it will propagate changes made to it by the user to the backend. This means that changes made in concurrent instantiations will not show up in other instantiations.
  • Modifications to user preferences made in two or more concurrent sessions will clobber the serverside persisted preferences per-key (see Add serverside persisted user preference trashed form list collapsedness #1018 (comment)); last one to make a change "wins". It may not be clear to a user that that is what's going on when they reinstantiate a tab and find themselves with different preferences than the ones they left the app with...
  • Whether it would be desirable to synchronize preferences across instantiations is an open question (for some hypothetical future display-size related preferences, users may not want their small-screen-session-preferences synced to their big-screen-session or vice versa). Currently the concensus seems to be that we don't really have such sensitive settings, and it is not likely that a user wants one preference in one session and another preference in another session.

Instead of replacing serverside user preference state wholesale
with what the client thinks the state is (which would clobber
any changes made in other client instantiations), patch up server
state incrementally.
@brontolosone brontolosone force-pushed the central_689-userpreferences-rb branch from 6d7d8ca to c9279bf Compare September 6, 2024 17:50
@brontolosone brontolosone marked this pull request as ready for review September 10, 2024 09:00
@brontolosone brontolosone marked this pull request as draft September 10, 2024 09:12
@brontolosone
Copy link
Contributor Author

Needs to be updated as the backend has changed quite a bit (getodk/central-backend@bd62997)

@brontolosone
Copy link
Contributor Author

Closing; superseded by #1024.

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.

1 participant