Store installed extension in a shared location
Description
The clustering support of extension currently have a major limitation: for it to properly work, all nodes need to be up and running when installing an extension on one of them. If a node is down during that time, it won't know about the installed extension, and it will have to be installed again on it when it comes back. Of course the same problem impact nodes which don't exist yet (unless they are created by cloning one of the existing nodes), when it starts, it won't know about the extensions installed on the other nodes.
As the whole metadata is already loaded in memory, what needs to be share is:
- events to warn other running node about new installs (this is currently what we have, but it might need to be modified to take into account the fact that the index is shared)
- the index storing which extension is installed where (this is currently stored directly in the local extension descriptor)
- local extension files (this is currently stored on local filesystem)
We could rely on events to share installed extensions (for example, at init ask other nodes if something has been installed), but another constraint is that we want to be able to completely avoid storing data that needs to be backuped in on the local filesystem.
We currently have 3 alternative storage locations:
- the database
- a Solr core
- blob storage (S3 or filesystem depending on the configuration)
One general challenge with the installed extensions index is that whatever is used to store them, it cannot come from an installed extension (i.e. the implementation of the storage must be part of the WAR). I also need to be initialized very early (at the very beginning of the application init, long before the first HTTP request), so it cannot rely on data stored in the standard database tables, for example.
Blob
The idea would be to use the blob API instead of directly manipulate local files.
Pro:
it is by far the easiest and safest in terms of backward dependency, because we could keep the exact same storage as now, just using a different API to manipulate files
also the best fit to store the extension binary files
Cons:
slower initialization as we have to search for all xed files and read them from the blob store
impossible to rely on a blob store implementation installed as extensions. It should not be a big constraint for S3, which is part of xwiki-platform, so we could decide to include it. But configuring any contrib blob store implementation would require to create a custom WAR.
Database
The idea would be to store the index in table(s) located in the database.
Pro:
it would allow searching through the index without storing it entirely in memory (even if it's not a strong need we currently have)
Cons:
impossible to reuse the current XWiki Hibernate API: it's initialized way too late, extension are allowed to inject custom map in the mapping before it's initialized
So it involves introducing and initializing another Hibernate endpoint that would be initialized during InstalledExtensionRepository component initialization and only contain the extension related tables.
generally not considered a good fit to store binary files, so we would need to find a solution to get the files of the extensions referenced in the index
Solr
The idea would be to store the index in a Solr core.
Installed extensions are already indexed in the extension_index core, so it would theoretically make sense to reuse it.
Pro:
it would allow searching through the index without storing it entirely in memory (even if it's not a strong need we currently have)
the index already mostly exist (mixed with available remote extensions)
Cons:
Solr cores are not very reliable, they never been designed to store data to backup, even if we do use them for that anyway already (events and ratings cores)
Introduce a new type of storage
The idea would be to introduce in XWiki support for a new type of store.
Thomas Mortagne