The issue
The settings table is (name, value, tag) with a unique index on (name, tag). It carries no record of who declared a setting or when it was last seen.
Consequently:
-
Settings left over from development and past refactors accumulate forever. They surface in the settings UI as text inputs in tabs under "Other", because manipulate_settings iterates {*all_settings.keys(), *definition.keys()} — anything in the DB gets rendered, declared or not. (webtool/views/views_admin.py:706)
-
Why we can't just delete undeclared rows. A row can be undeclared for at least five different reasons, and right now they are indistinguishable:
- genuinely removed from 4CAT (safe to delete and what we're after)
- owned by an extension that is uninstalled (must keep — they may re-add it and we do not want behavior to change; plus would be annoying)
- owned by an extension that is installed but disabled (keep it)
- owned by a module that failed to import this boot — syntax error, missing dependency, a bug we ship and patch next week (must keep;
module_loader.py:148-156 swallows this into missing_modules and only logs a warning)
- declared only on a first boot where
module_config.bin did not yet exist (this is a little chicken/egg type thing that we just need to make sure doesn't cause problems i.e. accidental deletions)
-
Two docstrings already promise this feature. ConfigManager.ensure_database claims "Deletes all stored settings not defined in 4CAT" — it does not; the deletion was dropped. ExtensionManipulator.uninstall_extension` claims "4CAT has general cleanup code for unreferenced settings" — but there is none.
Case 4 is the important one that worries me most and it applies to core processors just as much as to extensions. We do not want to delete a settings just because the module collector failed to import a module once.
The issue
The
settingstable is(name, value, tag)with a unique index on(name, tag). It carries no record of who declared a setting or when it was last seen.Consequently:
Settings left over from development and past refactors accumulate forever. They surface in the settings UI as text inputs in tabs under "Other", because
manipulate_settingsiterates{*all_settings.keys(), *definition.keys()}— anything in the DB gets rendered, declared or not. (webtool/views/views_admin.py:706)Why we can't just delete undeclared rows. A row can be undeclared for at least five different reasons, and right now they are indistinguishable:
module_loader.py:148-156swallows this intomissing_modulesand only logs a warning)module_config.bindid not yet exist (this is a little chicken/egg type thing that we just need to make sure doesn't cause problems i.e. accidental deletions)Two docstrings already promise this feature.
ConfigManager.ensure_databaseclaims "Deletes all stored settings not defined in 4CAT" — it does not; the deletion was dropped.ExtensionManipulator.uninstall_extension` claims "4CAT has general cleanup code for unreferenced settings" — but there is none.Case 4 is the important one that worries me most and it applies to core processors just as much as to extensions. We do not want to delete a settings just because the module collector failed to import a module once.