Skip to content

Commit

Permalink
Server: skip initial style storage
Browse files Browse the repository at this point in the history
Background: at project load time for all layers a copy of the style
is loaded and stored as a DOM document. This was implemented for
broken layers to make it possible to store the style back to the
project if a broken layer was kept in the project.

Of course this is not needed nor useful in a server context.

By introducing a new project load flag and using it in the server
config (projects) cache we allow to skip the initial storage of
styles for the server and cut the startup times of our test "monster"
project (~1000 PG layers) from 26 seconds to 15.

Before you ask: I chose to always store the original style
with the idea that we might have been able to use the original
style copy also to "restore" styles to their initial state.
This was never implemented, so I guess we might be good to
make the initial style copy selectively available for broken
layers only in order to speed up project loading in the general
case (desktop).
  • Loading branch information
elpaso committed Nov 30, 2020
1 parent 3b262f2 commit 9aa281a
Show file tree
Hide file tree
Showing 5 changed files with 11 additions and 3 deletions.
4 changes: 3 additions & 1 deletion python/core/auto_additions/qgsproject.py
Expand Up @@ -6,7 +6,9 @@
QgsProject.ReadFlag.FlagDontLoadLayouts.__doc__ = "Don't load print layouts. Improves project read time if layouts are not required, and allows projects to be safely read in background threads (since print layouts are not thread safe)."
QgsProject.FlagTrustLayerMetadata = QgsProject.ReadFlag.FlagTrustLayerMetadata
QgsProject.ReadFlag.FlagTrustLayerMetadata.__doc__ = "Trust layer metadata. Improves project read time. Do not use it if layers' extent is not fixed during the project's use by QGIS and QGIS Server."
QgsProject.ReadFlag.__doc__ = 'Flags which control project read behavior.\n\n.. versionadded:: 3.10\n\n' + '* ``FlagDontResolveLayers``: ' + QgsProject.ReadFlag.FlagDontResolveLayers.__doc__ + '\n' + '* ``FlagDontLoadLayouts``: ' + QgsProject.ReadFlag.FlagDontLoadLayouts.__doc__ + '\n' + '* ``FlagTrustLayerMetadata``: ' + QgsProject.ReadFlag.FlagTrustLayerMetadata.__doc__
QgsProject.FlagDontStoreOriginalStyles = QgsProject.ReadFlag.FlagDontStoreOriginalStyles
QgsProject.ReadFlag.FlagDontStoreOriginalStyles.__doc__ = "Skip the initial XML style storage for layers. Mainly useful in server's context where there is no chance that the user will save the project again."
QgsProject.ReadFlag.__doc__ = 'Flags which control project read behavior.\n\n.. versionadded:: 3.10\n\n' + '* ``FlagDontResolveLayers``: ' + QgsProject.ReadFlag.FlagDontResolveLayers.__doc__ + '\n' + '* ``FlagDontLoadLayouts``: ' + QgsProject.ReadFlag.FlagDontLoadLayouts.__doc__ + '\n' + '* ``FlagTrustLayerMetadata``: ' + QgsProject.ReadFlag.FlagTrustLayerMetadata.__doc__ + '\n' + '* ``FlagDontStoreOriginalStyles``: ' + QgsProject.ReadFlag.FlagDontStoreOriginalStyles.__doc__
# --
# monkey patching scoped based enum
QgsProject.FileFormat.Qgz.__doc__ = "Archive file format, supports auxiliary data"
Expand Down
1 change: 1 addition & 0 deletions python/core/auto_generated/qgsproject.sip.in
Expand Up @@ -40,6 +40,7 @@ open within the main QGIS application.
FlagDontResolveLayers,
FlagDontLoadLayouts,
FlagTrustLayerMetadata,
FlagDontStoreOriginalStyles,
};
typedef QFlags<QgsProject::ReadFlag> ReadFlags;

Expand Down
5 changes: 4 additions & 1 deletion src/core/qgsproject.cpp
Expand Up @@ -1627,7 +1627,10 @@ bool QgsProject::readProjectFile( const QString &filename, QgsProject::ReadFlags
// After bad layer handling we might still have invalid layers,
// store them in case the user wanted to handle them later
// or wanted to pass them through when saving
QgsLayerTreeUtils::storeOriginalLayersProperties( mRootGroup, doc.get() );
if ( !( flags & QgsProject::ReadFlag::FlagDontStoreOriginalStyles ) )
{
QgsLayerTreeUtils::storeOriginalLayersProperties( mRootGroup, doc.get() );
}

mRootGroup->removeCustomProperty( QStringLiteral( "loading" ) );

Expand Down
1 change: 1 addition & 0 deletions src/core/qgsproject.h
Expand Up @@ -121,6 +121,7 @@ class CORE_EXPORT QgsProject : public QObject, public QgsExpressionContextGenera
FlagDontResolveLayers = 1 << 0, //!< Don't resolve layer paths (i.e. don't load any layer content). Dramatically improves project read time if the actual data from the layers is not required.
FlagDontLoadLayouts = 1 << 1, //!< Don't load print layouts. Improves project read time if layouts are not required, and allows projects to be safely read in background threads (since print layouts are not thread safe).
FlagTrustLayerMetadata = 1 << 2, //!< Trust layer metadata. Improves project read time. Do not use it if layers' extent is not fixed during the project's use by QGIS and QGIS Server.
FlagDontStoreOriginalStyles = 1 << 3, //!< Skip the initial XML style storage for layers. Mainly useful in server's context where there is no chance that the user will save the project again.
};
Q_DECLARE_FLAGS( ReadFlags, ReadFlag )

Expand Down
3 changes: 2 additions & 1 deletion src/server/qgsconfigcache.cpp
Expand Up @@ -52,7 +52,8 @@ const QgsProject *QgsConfigCache::project( const QString &path, const QgsServerS
QgsStoreBadLayerInfo *badLayerHandler = new QgsStoreBadLayerInfo();
prj->setBadLayerHandler( badLayerHandler );

QgsProject::ReadFlags readFlags = QgsProject::ReadFlag();
// Always skip original styles storage
QgsProject::ReadFlags readFlags = QgsProject::ReadFlag() | QgsProject::ReadFlag::FlagDontStoreOriginalStyles ;
if ( settings )
{
// Activate trust layer metadata flag
Expand Down

0 comments on commit 9aa281a

Please sign in to comment.