Skip to content

Make `replace()` to not block because of non-existing item removal

Dāvis Mosāns requested to merge davism/kactivities-stats:async_replace into master

Currently when ResultModel is created it would invoke fetch() -> replace() which would wait on filesystem due to QFile.exists().

This causes significant delay (several minutes for me because that filesystem haven't mounted yet) of Plasma startup time because it's used by RecentUsageModel as can be seen by this trace

#0  0x00007f5659455a0e in statx () at /usr/lib/libc.so.6
#1  0x00007f56599bc830 in  () at /usr/lib/libQt5Core.so.5
#2  0x00007f56599b293d in  () at /usr/lib/libQt5Core.so.5
#3  0x00007f56599b532e in QFSFileEngine::fileFlags(QFlags<QAbstractFileEngine::FileFlag>) const () at /usr/lib/libQt5Core.so.5
#4  0x00007f565995af83 in QFile::exists() const () at /usr/lib/libQt5Core.so.5
#5  0x00007f55a06ce621 in KActivities::Stats::ResultModelPrivate::Cache::replace(QList<KActivities::Stats::ResultSet::Result> const&, int) (this=this@entry=0x55e6ade8aed0, newItems=..., from=from@entry=0) at /mnt/src/kactivities-stats/src/resultmodel.cpp:497
#6  0x00007f55a06ce857 in KActivities::Stats::ResultModelPrivate::fetch(int, int) (this=this@entry=0x55e6ade8aed0, from=from@entry=0, count=<optimized out>, count@entry=50) at /mnt/src/kactivities-stats/src/resultmodel.cpp:748
#7  0x00007f55a06cf0bc in KActivities::Stats::ResultModelPrivate::fetch(KActivities::Stats::ResultModelPrivate::Fetch) (this=0x55e6ade8aed0, mode=<optimized out>) at /mnt/src/kactivities-stats/src/resultmodel.cpp:767
#8  0x00007f55a0283e92 in RecentUsageModel::refresh() (this=0x55e6ae6e36c0) at /mnt/AUR/plasma-workspace-git/src/plasma-workspace/applets/kicker/plugin/recentusagemodel.cpp:555
#9  0x00007f55a026bc54 in QQmlPrivate::QQmlElement<RecentUsageModel>::QQmlElement() (this=0x55e6ae6e36c0) at /usr/include/qt/QtQml/qqmlprivate.h:139
#10 QQmlPrivate::createInto<RecentUsageModel>(void*) (memory=0x55e6ae6e36c0) at /usr/include/qt/QtQml/qqmlprivate.h:166
#11 0x00007f565aed53d3 in QQmlType::create(QObject**, void**, unsigned long) const () at /usr/lib/libQt5Qml.so.5
#12 0x00007f565af1c934 in QQmlObjectCreator::createInstance(int, QObject*, bool) () at /usr/lib/libQt5Qml.so.5
#13 0x00007f565af1e502 in QQmlObjectCreator::setPropertyBinding(QQmlPropertyData const*, QV4::CompiledData::Binding const*) () at /usr/lib/libQt5Qml.so.5
#14 0x00007f565af1eaf8 in QQmlObjectCreator::setupBindings(bool) () at /usr/lib/libQt5Qml.so.5
#15 0x00007f565af1b72b in QQmlObjectCreator::populateInstance(int, QObject*, QObject*, QQmlPropertyData const*) () at /usr/lib/libQt5Qml.so.5
#16 0x00007f565af1c30f in QQmlObjectCreator::createInstance(int, QObject*, bool) () at /usr/lib/libQt5Qml.so.5
#17 0x00007f565af16553 in QQmlObjectCreator::create(int, QObject*, QQmlInstantiationInterrupt*, int) () at /usr/lib/libQt5Qml.so.5
#18 0x00007f565aebbbb2 in QQmlIncubatorPrivate::incubate(QQmlInstantiationInterrupt&) () at /usr/lib/libQt5Qml.so.5
#19 0x00007f565aebc32e in QQmlEnginePrivate::incubate(QQmlIncubator&, QQmlContextData*) () at /usr/lib/libQt5Qml.so.5
#20 0x00007f565aebc5af in QQmlComponent::create(QQmlIncubator&, QQmlContext*, QQmlContext*) () at /usr/lib/libQt5Qml.so.5
#21 0x00007f565b8e696a in KDeclarative::QmlObject::completeInitialization(QHash<QString, QVariant> const&) (initialProperties=<optimized out>, this=0x55e6adb41ce0) at /mnt/AUR/kdeclarative-git/src/kdeclarative/src/kdeclarative/qmlobject.cpp:311
#22 KDeclarative::QmlObject::completeInitialization(QHash<QString, QVariant> const&) (this=0x55e6adb41ce0, initialProperties=<optimized out>) at /mnt/AUR/kdeclarative-git/src/kdeclarative/src/kdeclarative/qmlobject.cpp:293
#23 0x00007f565bc93b60 in PlasmaQuick::AppletQuickItem::init() (this=this@entry=0x55e6adb41e80) at /mnt/AUR/plasma-framework-git/src/plasma-framework/src/plasmaquick/appletquickitem.cpp:653
#24 0x00007f563c2bf17f in AppletInterface::init() (this=0x55e6adb41e80) at /mnt/AUR/plasma-framework-git/src/plasma-framework/src/scriptengines/qml/plasmoid/appletinterface.cpp:149
#25 0x00007f565bc95621 in PlasmaQuick::AppletQuickItem::itemChange(QQuickItem::ItemChange, QQuickItem::ItemChangeData const&) (this=0x55e6adb41e80, change=QQuickItem::ItemSceneChange, value=...) at /mnt/AUR/plasma-framework-git/src/plasma-framework/src/plasmaquick/appletquickitem.cpp:935
#26 0x00007f565b387e21 in QQuickItemPrivate::refWindow(QQuickWindow*) () at /usr/lib/libQt5Quick.so.5
#27 0x00007f565b387ddd in QQuickItemPrivate::refWindow(QQuickWindow*) () at /usr/lib/libQt5Quick.so.5
#28 0x00007f565b38bc51 in QQuickItem::setParentItem(QQuickItem*) () at /usr/lib/libQt5Quick.so.5
#29 0x00007f565bca37b2 in PlasmaQuick::ContainmentViewPrivate::setContainment(Plasma::Containment*) (this=0x55e6ae0230e0, cont=<optimized out>) at /mnt/AUR/plasma-framework-git/src/plasma-framework/src/plasmaquick/containmentview.cpp:122
#30 0x000055e6ac092efa in ShellCorona::createWaitingPanels() (this=0x55e6ad7fa680) at /mnt/AUR/plasma-workspace-git/src/plasma-workspace/shell/shellcorona.cpp:1303
#31 0x00007f5659a41463 in  () at /usr/lib/libQt5Core.so.5
#32 0x00007f5659a4369f in QTimer::timeout(QTimer::QPrivateSignal) () at /usr/lib/libQt5Core.so.5
#33 0x00007f5659a34766 in QObject::event(QEvent*) () at /usr/lib/libQt5Core.so.5
#34 0x00007f565a6b01c6 in QApplicationPrivate::notify_helper(QObject*, QEvent*) () at /usr/lib/libQt5Widgets.so.5
#35 0x00007f5659a105aa in QCoreApplication::notifyInternal2(QObject*, QEvent*) () at /usr/lib/libQt5Core.so.5
#36 0x00007f5659a5bdd5 in QTimerInfoList::activateTimers() () at /usr/lib/libQt5Core.so.5
#37 0x00007f5659a5c3ba in  () at /usr/lib/libQt5Core.so.5
#38 0x00007f5657d6d163 in g_main_context_dispatch () at /usr/lib/libglib-2.0.so.0
#39 0x00007f5657dc39e9 in  () at /usr/lib/libglib-2.0.so.0
#40 0x00007f5657d6a6c5 in g_main_context_iteration () at /usr/lib/libglib-2.0.so.0
#41 0x00007f5659a5c57a in QEventDispatcherGlib::processEvents(QFlags<QEventLoop::ProcessEventsFlag>) () at /usr/lib/libQt5Core.so.5
#42 0x00007f5659a0888b in QEventLoop::exec(QFlags<QEventLoop::ProcessEventsFlag>) () at /usr/lib/libQt5Core.so.5
#43 0x00007f5659a13fd7 in QCoreApplication::exec() () at /usr/lib/libQt5Core.so.5
#44 0x000055e6ac0673f2 in main(int, char**) (argc=<optimized out>, argv=<optimized out>) at /mnt/AUR/plasma-workspace-git/src/plasma-workspace/shell/main.cpp:243

I think it's bad design that replace that does this. IMHO it should be handled by a separate task. Anyway this is very simple fix to just do it in separate thread and seems to be working fine. Only I don't know if this is thread-safe and if we don't need some mutex somewhere...

Merge request reports