subsurface/core/settings
Dirk Hohndel 7fa031b648 cloudstorage: try to pick between multiple cloud servers
The backend infrastructure will soon be able to support more than one
cloud server which automagically stay in sync with each other.

One critical requirement for that to work is that once a session was
started with one of the servers, the complete session happens with that
server - we must not switch from server to server while doing a git
transaction. To make sure that's the case, we aren't trying to use DNS
tricks to make this load balancing scheme work, but instead try to
determine at program start which server is the best one to use.

Right now this is super simplistic. Two servers, one in the US, one in
Europe. By default we use the European server (most of our users appear
to be in Europe), but if we can figure out that the client is actually
in the Americas, use the US server. We might improve that heuristic over
time, but as a first attempt it seems not entirely bogus.

The way this is implemented is a simple combination of two free
webservices that together appear to give us a very reliable estimate
which continent the user is located on.

api.ipify.org gives us our external IP address
ip-api.com gives us the continent that IP address is on

If any of this fails or takes too long to respond, we simply ignore it
since either server will work. One oddity is that if we decide to change
servers we only change the settings that are stored on disk, not the
runtime preferences. This goes back to the comment above that we have to
avoid changing servers in mid sync.

Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2021-04-19 12:51:01 -07:00
..
qPref.cpp
qPref.h
qPrefCloudStorage.cpp cloudstorage: try to pick between multiple cloud servers 2021-04-19 12:51:01 -07:00
qPrefCloudStorage.h cloudstorage: add API to just update on-disk setting 2021-04-19 12:51:01 -07:00
qPrefDisplay.cpp revert preference settings for title color 2020-11-04 14:51:55 -08:00
qPrefDisplay.h revert preference settings for title color 2020-11-04 14:51:55 -08:00
qPrefDiveComputer.cpp
qPrefDiveComputer.h
qPrefDivePlanner.cpp
qPrefDivePlanner.h
qPrefEquipment.cpp prefs: add option to display only actually used tanks 2020-12-13 11:49:59 -08:00
qPrefEquipment.h prefs: add option to display only actually used tanks 2020-12-13 11:49:59 -08:00
qPrefGeneral.cpp
qPrefGeneral.h
qPrefGeocoding.cpp
qPrefGeocoding.h
qPrefLanguage.cpp
qPrefLanguage.h
qPrefLocationService.cpp
qPrefLocationService.h
qPrefLog.cpp
qPrefLog.h
qPrefMedia.cpp
qPrefMedia.h
qPrefPartialPressureGas.cpp
qPrefPartialPressureGas.h
qPrefPrivate.cpp
qPrefPrivate.h
qPrefProxy.cpp
qPrefProxy.h
qPrefTechnicalDetails.cpp mobile: add GF fields for ceiling calculation 2021-01-19 12:34:46 -08:00
qPrefTechnicalDetails.h
qPrefUnit.cpp
qPrefUnit.h
qPrefUpdateManager.cpp preferences: remove pointless member 2021-01-06 10:18:23 -08:00
qPrefUpdateManager.h preferences: remove pointless member 2021-01-06 10:18:23 -08:00
README.md

Short explanation of how qPref works

System startup:

core/qt-init.cpp init_qt_late()

does

qPref::load();

to load all properties from all qPref* classes

System shutdown:

subsurface-mobile-main.cpp and subsurface-desktop-main.cpp main()

calls

call qPref::sync()

to save all changes to disk, this is needed because part of the program modifies struct preferences instead of calling the set method.

EXCEPTION:

Variables not present in struct preferences (local static variables in the class are not written, see later.

System startup/shutdown common handling:

qPref::load() calls qPref::doSync(false)
qPref::sync() calls qPref::doSync(true)

qPrefDoSync()

qPref::doSync() calls qPref::doSync() for all qPref* classes Meaning qPref knows which classes exist, but not which variables

qPref*::doSync() calls

disk_<variable name>() for each variable

EXCEPTION:

some variables are not in struct preferences, but local static variables which can only be accessed through the set/get functions, therefore there are no need to sync them

	if (!doSync) // meaining load
		load_<variable_name>()

qPref*::disk_*()

qPref*::disk_*() calls qPrefPrivate::propSetValue to save a property, and qPrefPrivate::propValue() to read a property. The function also keeps struct preferences in sync.

qPrefPrivate::propSetValue()

qPrefPrivate::propSetValue() is static and calls QSettings to write property

qPrefPrivate::propValue()

qPrefPrivate::propValue() is static and calls QSettings to read property

macros

the macros are defined in qPrefPrivate.h

the macros are used in qPref*cpp

Reading properties

Reading a property is done through an inline function, and thus no more expensive than accessing the variable directly.

qPref*::<variable_name>()

Setting properties

Setting a property is done through a dedicated set function which are static to simplify the call:

qPref<class>::set_<variable_name>(value)

like:

qPrefDisplay::animation_speed(500);

the set function updates struct preferences (if not a local variable), and saves the property to disk, however save is only done if the variable is changed.

Updating struct preferences

When a program part updates struct preferences directly, changes are NOT saved to disk if the programm crashes, otherwise all variables are saved to disk with the program exists.