Port KCM loading & querying away from KServiceTypeTrader
Open, Needs TriagePublic

Description

Currently the KCMs are queried using KServiceTypeTrader, which we are trying to get rid of. It also forces the consumers to install the old desktop file, instead of just using embedded JSON metadata.

Some thoughts on this (brainstoming ;)):

  • We could set the type for the desktop file to application and combine this with OnlyShowIn=KDE, then one could use KApplicationTrader to query the KCMs. That makes sense considering that the KCMs which you can open from KRunner & the app launcher are treated like application.
  • Alternatively one could make KSycoca index the JSON plugins, at least for a specific namespaces. Then we would not need to install the desktop files at all. To provide a query mechanism the type could be set to application, as suggested above.
  • Make the consumers parse the JSON plugins using KPluginLoader. This would have the disadvantage that the launching could not be done using a simple ApplicationLauncherJob
alex created this task.May 26 2021, 5:48 AM
alex updated the task description. (Show Details)May 29 2021, 3:19 PM
alex added a comment.May 29 2021, 3:22 PM

From discussion in KF6 weekly: Option 3 was seen as the best solution. Then we have a utility method in KCMUtils which also does some caching of the plugins.

For avoiding the KServiceTrader query language the plugins can get installed into specific subdirs. This way the KCMs that should be displayed into kcmshell/systemsettings/kinfocenter have their own subdir.

alex added a subscriber: apol.Jul 28 2021, 1:22 PM

We would also need some unified plugin namespaces.
My suggestion would be:
plasma/systemsettings systemsettings
plasma/kinfofenter
kinfocenter
kcontrol // unified place for global KCMs, like trash KCM

Not sure what to best do with the QWidget KCMs: I guess we want to get rid of KServiceTypeTrader, but also do not load them in systemsettings in Plasma 6. But that is really a Plasma detail and not sth. which should be blocking for frameworks. My suggestion would be to make a namespace like plasma/kcms for that stuff which is only for Plasma5 relevant.

An idea could to provide a query method in KCMUtils which searches those namespace or the consumers (systemsettings, runner and kcmshell) have to search for plugins manually using KPluginLoader in the respective namespaces.

@apol @davidedmundson

sitter added a subscriber: sitter.Aug 2 2021, 3:28 PM

Why wouldn't we just use kcontrol/ for everything?

alex added a comment.Aug 2 2021, 3:45 PM

It would require a filter mechanism like the currently used X-KDE-ParentApp keyword where we have to load all the metadata to find the matching ones - which is very unperformant.

sitter added a comment.Aug 3 2021, 1:09 PM

I don't think you'll get around a filter system, about-distro is both in settings and infocenter so that would presumably go in kcontrol/. The way I see it we need to be able to codify 0:N parent apps with N>=0 but the proposal would only allow 0:N with N<=1.

Indeed another point is that various applications have had loaded kcms over the years to supply (e.g.) proxy settings from inside the app when the app isn't run inside a Plasma context (I think amarok had that at some point). If we encode the parentapp through the path that means we cannot ever change the parent app without breaking applications because we had forced them to hardcode the parentapp path.

Do we have measurements on the performance impact of reading plugin metadata of all KCMs without cache assistance?

alex added a comment.Aug 3 2021, 1:30 PM

Do we have measurements on the performance impact of reading plugin metadata of all KCMs without cache assistance?

KPluginLoader::findPlugins(QStringLiteral("plasma/kinfocenter")); takes ~ 4 msec each iterations. KServiceTypeTrader::self()->query(QStringLiteral("KCModule"), QStringLiteral("[X-KDE-ParentApp] == 'kinfocenter'")); ~ 1 msec each iteration.

Of course that is with there only being 16 plugin in the kinfocenter namespace.

Alternatively the about-distro thingy be handled as a special case where we load it by name in systemsettings, then we would have this issue. That should only be 3 lines in systemsettings.

sitter added a comment.Aug 3 2021, 2:25 PM

I'm not sure 4msec are even worth the amount of text we are spending on this... it is not really an interesting metric though. What we care about is the difference between loading all kcms and loading only the topical ones:

PASS   : DatabaseBenchmark::allKCMS()
RESULT : DatabaseBenchmark::allKCMS():
     9.1 msecs per iteration (total: 73, iterations: 8)
PASS   : DatabaseBenchmark::infoKCMs()
RESULT : DatabaseBenchmark::infoKCMs():
     0.76 msecs per iteration (total: 98, iterations: 128)
PASS   : DatabaseBenchmark::settingKCMs()
RESULT : DatabaseBenchmark::settingKCMs():
     5.6 msecs per iteration (total: 90, iterations: 16)
PASS   : DatabaseBenchmark::allSettingsAndInfos()
RESULT : DatabaseBenchmark::allSettingsAndInfos():
     6.3 msecs per iteration (total: 51, iterations: 8)

(that is with 114 kcms, 43 settings, 7 infos - on my system)

Which, if anything, suggests that we should move all the third party kcms somewhere else.

  • kcms/private/$app/ for app specific kcms (choqok has like a mountain of them) so an app can load its own kcms as fast as possible while not getting in the way of shared kcms
  • kcms/shared/ for everything that is shared (or call it plasma/ for all I care, but since KIO has KCMs stills that seems a bit of a meh name?)

with the express understanding that everything in private/ is not meant for use outside its application.

Indeed to take this in a completely different direction: if we consider the way the load times scale a concern we should really just make the loading async (QFuture or something) or cache it. Splitting dirs doesn't help one bit if we end up having 100 settings kcms by 2025 anyway. Plus all of this is subject to vendor extension.

alex added a comment.Aug 3 2021, 6:53 PM

Splitting dirs doesn't help one bit if we end up having 100 settings kcms by 2025 anyway. Plus all of this is subject to vendor extension.

The entire idea behind the namespaces is that we only need to query plugins in a certain dir. Meaning we might have 100 KCMs for systemsettings, but could have 1000 in total that don't want to integrate.

I'm not sure 4msec are even worth the amount of text we are spending on this

Then one could say the same about that one KCM we could easily work around or maybe just create a symlink ;)

I had a discussion with Aleix recently where he stressed that IO is very slow on deceives that are supported by plasma-mobile. Also I am on a relatively decent computer with an ssd...

Which, if anything, suggests that we should move all the third party kcms somewhere else.

Why does this have to do anything with apps that don't want to integrate themselves in systemsettings or kinfocenter? They can choose a namespace based on their app, like kwin which uses kwin/effects/configs/. IMHO those can be left alone in their namespace and we don't need to worry about them.

If we encode the parentapp through the path that means we cannot ever change the parent app without breaking applications because we had forced them to hardcode the parentapp path.

How is this any different from the current approach where we hardcode the parent app in the service type file? In any cases we would need compatibility logic.

The way I see it we need to be able to codify 0:N parent apps with N>=0 but the proposal would only allow 0:N with N<=1.

Are there legitimate usecases except the one KCM? If we really go down that path we could not port anything away from KServiceTypeTrader, because a service file can have multiple and possibly unrelated service types. It could be an external systemsettings external tool, krunner plugin and dolphin context menu at the same time,

I had a discussion with Aleix recently where he stressed that IO is very slow on deceives that are supported by plasma-mobile. Also I am on a relatively decent computer with an ssd...

Do we have an IO benchmark of loading the metadata?

Are there legitimate usecases except the one KCM?

plasma-disks could do this, trash could do this, kded could do this, heck, baloo even kinda did it albeit as two separate KCMS IIRC. If IO speed is a concern surely caching is the answer, not path changes. Like why would even open the library file just to get access to the metadata if that is too slow. Have a cachefile, open the cache, only open the library if and when the user activates it in the UI.

alex added a comment.Aug 4 2021, 3:41 PM

I don't think you'll get around a filter system

The plugin namespaces are already a filter mechanism themselves, which is enough for most usages.

plasma-disks could do this, trash could do this, kded could do this, heck, baloo even kinda did it albeit as two separate KCMS IIRC.

Then how about using plasma/kcms as "shared" dir, plasma/kcms/systemsettings for systemsettings only and plasma/kcms/kinfocenter for the kinfocenter specific ones. Then we should have the shared KCMs handled, still have the advantages of the namespaces and could extend it in the future.

apol added a comment.Aug 4 2021, 4:04 PM

My comment was mostly aimed at the plasmashell profiling (i.e. plasmoids) we did for the pinebook. KCM delays should be less stressful to performance because we don't trigger it as the system is starting up.

I can run any benchmark on several pine devices, just tell me which would be useful.

In T14517#261296, @alex wrote:

I don't think you'll get around a filter system

The plugin namespaces are already a filter mechanism themselves, which is enough for most usages.

plasma-disks could do this, trash could do this, kded could do this, heck, baloo even kinda did it albeit as two separate KCMS IIRC.

Then how about using plasma/kcms as "shared" dir, plasma/kcms/systemsettings for systemsettings only and plasma/kcms/kinfocenter for the kinfocenter specific ones. Then we should have the shared KCMs handled, still have the advantages of the namespaces and could extend it in the future.

I suppose.

I maintain that as per my benchmark the plasma stuff isn't really the problem though. The third party stuff is. SS loads almost all the shared kcms anyway, whether you load them by path or load them by path and then check which apps they associated with makes no practical difference. By extension whether you pack them in separate dirs for SS and KIC or not doesn't really matter either. Not having to iterate the third party kcms that will never get loaded is important.

But as mentioned if IO is a concern we should forget about the paths and cache stuff instead. If IO is a concern we don't want to even open the file until we actually need it, and we only need it when the KCM needs displaying.

alex added a comment.Aug 10 2021, 3:07 PM

I just want to say that the namespace itself is already a filter mechanism. Considering that we always need to use them when listing plugin we can choose namespaces that already do the filtering for us :) Not having to open the files needlessly is a positive side effect.

alex added a comment.Aug 10 2021, 6:54 PM

PS: As you can see from the second suggestion in this task I already considered some ksycoca magic, but that was discouraged in the KF6 weekly and I did not find strong arguments for it either.

alex added a comment.Nov 1 2021, 11:02 AM

Notes from KF6 weekly:

  • JSON KCM loading works fine
  • URL to pin KCMs to taskbar requires a .desktop file
  • would require to keep the .desktop files around for KCMs that behave "application-like"
  • not an good alternative: keep .desktop-based plugin loading code and json from desktop generation around

Because of this we agreed on having separate desktop files for pinning the KCMs, those will have a NoDisplay entry to make sure they do not interfere with the normal app search.

alex moved this task from Backlog to In Progress on the KF6 board.Nov 21 2021, 5:48 AM
alex renamed this task from Consider creating replacement for desktop file KCM loading & querying to Port KCM loading & querying away from KServiceTypeTrader.Jan 4 2022, 4:37 PM
alex moved this task from In Progress to Done on the KF6 board.Mar 4 2023, 10:19 AM