<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://docs.moodle.org/dev/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Ashleyholman</id>
	<title>MoodleDocs - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://docs.moodle.org/dev/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Ashleyholman"/>
	<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/Special:Contributions/Ashleyholman"/>
	<updated>2026-08-07T05:17:38Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.43.5</generator>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Talk:Server_clustering_improvements_proposal&amp;diff=41308</id>
		<title>Talk:Server clustering improvements proposal</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Talk:Server_clustering_improvements_proposal&amp;diff=41308"/>
		<updated>2013-07-10T07:20:58Z</updated>

		<summary type="html">&lt;p&gt;Ashleyholman: Created page with &amp;quot;== $CFG-&amp;gt;sslproxy == The problem with this setting is that it requires your whole site to be HTTPS, ie. wwwroot must begin with &amp;quot;https://&amp;quot;.  This doesn&amp;#039;t allow for having only...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== $CFG-&amp;gt;sslproxy ==&lt;br /&gt;
The problem with this setting is that it requires your whole site to be HTTPS, ie. wwwroot must begin with &amp;quot;https://&amp;quot;.  This doesn&#039;t allow for having only partly HTTPS, like can be done with the $CFG-&amp;gt;loginhttps feature.  Moodle can be informed if a page is HTTPS or not by checking for a header set by the SSL termination device.  So, it should be an advanced configuration option to enter a HTTP header which, if present, indicates the page was accessed under HTTPS.  This would allow for mixed HTTP/HTTPS site with a SSL proxy.&lt;/div&gt;</summary>
		<author><name>Ashleyholman</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=File_Storage_Plugintype&amp;diff=35918</id>
		<title>File Storage Plugintype</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=File_Storage_Plugintype&amp;diff=35918"/>
		<updated>2012-10-25T10:00:03Z</updated>

		<summary type="html">&lt;p&gt;Ashleyholman: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Introduction ==&lt;br /&gt;
This page details a proposal to introduce a new plugin type for File Storage.&lt;br /&gt;
&lt;br /&gt;
== Purpose ==&lt;br /&gt;
Moodle currently only supports one method for storing files, which is on a local filesystem.  In order to scale Moodle to multiple machines, a shared filesystem must be used in order to keep the files synchronised between all nodes in the cluster.  This dependence on a shared filesystem becomes a bottleneck when scaling Moodle to large clusters.&lt;br /&gt;
&lt;br /&gt;
In Moodle 2.3, the File Storage API introduced a class (file_storage) that was responsible for all reading and writing to the &amp;quot;file pool&amp;quot;.  Any code that wants to read or write files does so via the file_storage class.  This separates code from the particular implementation of how files are stored and retrieved.&lt;br /&gt;
&lt;br /&gt;
By extending the file_storage class and overriding methods, it is possible to change Moodle&#039;s file storage method to non-filesystem-based solutions (such as Amazon S3, etc).  Whilst this approach currently works, a new plugin type would allow this to be done without having to patch core.&lt;br /&gt;
&lt;br /&gt;
== Design ==&lt;br /&gt;
* New plugin type to go into a new directory called &amp;quot;storage&amp;quot;, eg. storage/filesystem/, storage/s3/.&lt;br /&gt;
* New abstract base class for file_storage and stored_file.  The methods should match the public and protected methods currently in file_storage and stored_file.&lt;br /&gt;
* The current file_storage and stored_file classes should move into a plugin, storage/filesystem/ and be made to extend the base class.&lt;br /&gt;
* A new admin configuration setting, $CFG-&amp;gt;storagemethod to be added which is set to one of the plugin names (&#039;filesystem&#039; by default).&lt;br /&gt;
* The get_file_storage() method in moodlelib should be modified to check $CFG-&amp;gt;storagemethod and to return an instance of the enabled storage plugin. The other code currently in get_file_storage() which does filesystem-specific checks should be moved into the storage/filesystem/ plugin&#039;s constructor.&lt;br /&gt;
* New section under Site Administration -&amp;gt; Plugins -&amp;gt; Storage can be used for configuring file storage plugins.&lt;br /&gt;
&lt;br /&gt;
== Code layout for storage plugins ==&lt;br /&gt;
* storage/&amp;lt;plugin&amp;gt;/lib.php:  should contain a class which extends the file_storage base class.&lt;br /&gt;
* plugins should also include a class which extends stored_file.  this can go in lib.php or in a separate file - it doesn&#039;t matter since the plugin&#039;s stored_file class only needs to be included/instantiated by its file_storage class&lt;br /&gt;
&lt;br /&gt;
== Audit of all $CFG-&amp;gt;dataroot usage ==&lt;br /&gt;
An audit needs to be done of all usage of $CFG-&amp;gt;dataroot in core.  No code should write to dataroot if it is required to be readable on subsequent page requests.  It is OK to write to $CFG-&amp;gt;cachedir for caching purposes (ie. the data can be cleared at any point without causing problems) or $CFG-&amp;gt;tempdir for temp usage (temp files whos lifetime only spans a single script execution).  Any usage of $CFG-&amp;gt;dataroot for persistance should be replaced by a call to the storage API.&lt;br /&gt;
&lt;br /&gt;
Effected areas identified by the audit are:&lt;br /&gt;
* Custom language packs / language overrides: Currently these are stored in $CFG-&amp;gt;dataroot and need to be shared between hosts.  These need to move elsewhere (eg. database or storage API).&lt;br /&gt;
* Database module (mod/data/) presets: These are stored in $CFG-&amp;gt;dataroot/data/preset/ - they should be moved to a filearea/component in the storage API.&lt;br /&gt;
&lt;br /&gt;
* This list is hugely incomplete...&lt;br /&gt;
&lt;br /&gt;
== Third party plugins ==&lt;br /&gt;
The CONTRIB plugin review process should include an additional step to check for direct usage of $CFG-&amp;gt;dataroot.  Plugin developers should be encouraged to use the storage API so that users who are not using the filesystem storage method can use their plugin without bugs.&lt;br /&gt;
&lt;br /&gt;
== Migration between storage methods ==&lt;br /&gt;
A CLI script for migrating between storage methods should be added into admin/cli/.  There will be no need for storage plugins to implement their own migration routines as this can be implemented in the base class as follows:&lt;br /&gt;
* create an instance of the current file storage plugin ($fs = get_file_storage())&lt;br /&gt;
* also create an instance of the new plugin (eg. $newfs = new s3_file_storage())&lt;br /&gt;
* call the migrate() method: $fs-&amp;gt;migrate($newfs);&lt;br /&gt;
* the migrate method is implemented in the base class (doesnt need to be implemented in plugins). it does:&lt;br /&gt;
** SQL query: select distinct contenthash from mdl_files;&lt;br /&gt;
** for each result:&lt;br /&gt;
*** call $fs to retrieve contents of contenthash and store in a temp file (this will require a new method protected method to be added to the file_storage base class which needs to be implemented in each plugin). eg. $fs-&amp;gt;copy_contenthash_to($contenthash, $temppath);&lt;br /&gt;
*** call $newfs-&amp;gt;add_file_to_pool($temppath);&lt;br /&gt;
Note: this method of migration could be very slow for large sites, so advanced users may which to implement their own strategys for migration.&lt;br /&gt;
&lt;br /&gt;
== Enhancements to the file_storage interface ==&lt;br /&gt;
- An option should be added to stored_file::readfile() for serving a range request.  This will prevent file.php from having to call $fs-&amp;gt;get_content_file_handle() which would force the storage plugin to download the entire file.&lt;br /&gt;
&lt;br /&gt;
== Note re latency ==&lt;br /&gt;
File storage plugins that use network connections to send/retrieve file contents are likely to introduce more latency into file operations than the default filesystem method.  This could effect pages that do many file operations (eg. restoring a backup, extracting scorm packages).  If backups are made asynchronous this be less of a problem.  If SCORM packages are also a problem then they could be queued as well.&lt;/div&gt;</summary>
		<author><name>Ashleyholman</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=File_Storage_Plugintype&amp;diff=35916</id>
		<title>File Storage Plugintype</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=File_Storage_Plugintype&amp;diff=35916"/>
		<updated>2012-10-25T09:25:15Z</updated>

		<summary type="html">&lt;p&gt;Ashleyholman: /* Code layout for storage plugins */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Introduction ==&lt;br /&gt;
This page details a proposal to introduce a new plugin type for File Storage.&lt;br /&gt;
&lt;br /&gt;
== Purpose ==&lt;br /&gt;
Moodle currently only supports one method for storing files, which is on a local filesystem.  In order to scale Moodle to multiple machines, a shared filesystem must be used in order to keep the files synchronised between all nodes in the cluster.  This dependence on a shared filesystem becomes a bottleneck when scaling Moodle to large clusters.&lt;br /&gt;
&lt;br /&gt;
In Moodle 2.3, the File Storage API introduced a class (file_storage) that was responsible for all reading and writing to the &amp;quot;file pool&amp;quot;.  Any code that wants to read or write files does so via the file_storage class.  This separates code from the particular implementation of how files are stored and retrieved.&lt;br /&gt;
&lt;br /&gt;
By extending the file_storage class and overriding methods, it is possible to change Moodle&#039;s file storage method to non-filesystem-based solutions (such as Amazon S3, etc).  Whilst this approach currently works, a new plugin type would allow this to be done without having to patch core.&lt;br /&gt;
&lt;br /&gt;
== Design ==&lt;br /&gt;
* New plugin type to go into a new directory called &amp;quot;storage&amp;quot;, eg. storage/filesystem/, storage/s3/.&lt;br /&gt;
* New abstract base class for file_storage and stored_file.  The methods should match the public and protected methods currently in file_storage and stored_file.&lt;br /&gt;
* The current file_storage and stored_file classes should move into a plugin, storage/filesystem/ and be made to extend the base class.&lt;br /&gt;
* A new admin configuration setting, $CFG-&amp;gt;storagemethod to be added which is set to one of the plugin names (&#039;filesystem&#039; by default).&lt;br /&gt;
* The get_file_storage() method in moodlelib should be modified to check $CFG-&amp;gt;storagemethod and to return an instance of the enabled storage plugin. The other code currently in get_file_storage() which does filesystem-specific checks should be moved into the storage/filesystem/ plugin&#039;s constructor.&lt;br /&gt;
* New section under Site Administration -&amp;gt; Plugins -&amp;gt; Storage can be used for configuring file storage plugins.&lt;br /&gt;
&lt;br /&gt;
== Code layout for storage plugins ==&lt;br /&gt;
* storage/&amp;lt;plugin&amp;gt;/lib.php:  should contain a class which extends the file_storage base class.&lt;br /&gt;
* plugins should also include a class which extends stored_file.  this can go in lib.php or in a separate file - it doesn&#039;t matter since the plugin&#039;s stored_file class only needs to be included/instantiated by its file_storage class&lt;br /&gt;
&lt;br /&gt;
== Audit of all $CFG-&amp;gt;dataroot usage ==&lt;br /&gt;
An audit needs to be done of all usage of $CFG-&amp;gt;dataroot in core.  No code should write to dataroot if it is required to be readable on subsequent page requests.  It is OK to write to $CFG-&amp;gt;cachedir for caching purposes (ie. the data can be cleared at any point without causing problems) or $CFG-&amp;gt;tempdir for temp usage (temp files whos lifetime only spans a single script execution).  Any usage of $CFG-&amp;gt;dataroot for persistance should be replaced by a call to the storage API.&lt;br /&gt;
&lt;br /&gt;
Effected areas identified by the audit are:&lt;br /&gt;
* Custom language packs / language overrides: Currently these are stored in $CFG-&amp;gt;dataroot and need to be shared between hosts.  These need to move elsewhere (eg. database or storage API).&lt;br /&gt;
* Database module (mod/data/) presets: These are stored in $CFG-&amp;gt;dataroot/data/preset/ - they should be moved to a filearea/component in the storage API.&lt;br /&gt;
&lt;br /&gt;
== Third party plugins ==&lt;br /&gt;
The CONTRIB plugin review process should include an additional step to check for direct usage of $CFG-&amp;gt;dataroot.  Plugin developers should be encouraged to use the storage API so that users who are not using the filesystem storage method can use their plugin without bugs.&lt;br /&gt;
&lt;br /&gt;
== Migration between storage methods ==&lt;br /&gt;
A CLI script for migrating between storage methods should be added into admin/cli/.  There will be no need for storage plugins to implement their own migration routines as this can be implemented in the base class as follows:&lt;br /&gt;
* create an instance of the current file storage plugin ($fs = get_file_storage())&lt;br /&gt;
* also create an instance of the new plugin (eg. $newfs = new s3_file_storage())&lt;br /&gt;
* call the migrate() method: $fs-&amp;gt;migrate($newfs);&lt;br /&gt;
* the migrate method is implemented in the base class (doesnt need to be implemented in plugins). it does:&lt;br /&gt;
** SQL query: select distinct contenthash from mdl_files;&lt;br /&gt;
** for each result:&lt;br /&gt;
*** call $fs to retrieve contents of contenthash and store in a temp file (this will require a new method protected method to be added to the file_storage base class which needs to be implemented in each plugin). eg. $fs-&amp;gt;copy_contenthash_to($contenthash, $temppath);&lt;br /&gt;
*** call $newfs-&amp;gt;add_file_to_pool($temppath);&lt;br /&gt;
Note: this method of migration could be very slow for large sites, so advanced users may which to implement their own strategys for migration.&lt;/div&gt;</summary>
		<author><name>Ashleyholman</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=File_Storage_Plugintype&amp;diff=35915</id>
		<title>File Storage Plugintype</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=File_Storage_Plugintype&amp;diff=35915"/>
		<updated>2012-10-25T09:16:41Z</updated>

		<summary type="html">&lt;p&gt;Ashleyholman: Created page with &amp;quot;== Introduction == This page details a proposal to introduce a new plugin type for File Storage.  == Purpose == Moodle currently only supports one method for storing files, which...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Introduction ==&lt;br /&gt;
This page details a proposal to introduce a new plugin type for File Storage.&lt;br /&gt;
&lt;br /&gt;
== Purpose ==&lt;br /&gt;
Moodle currently only supports one method for storing files, which is on a local filesystem.  In order to scale Moodle to multiple machines, a shared filesystem must be used in order to keep the files synchronised between all nodes in the cluster.  This dependence on a shared filesystem becomes a bottleneck when scaling Moodle to large clusters.&lt;br /&gt;
&lt;br /&gt;
In Moodle 2.3, the File Storage API introduced a class (file_storage) that was responsible for all reading and writing to the &amp;quot;file pool&amp;quot;.  Any code that wants to read or write files does so via the file_storage class.  This separates code from the particular implementation of how files are stored and retrieved.&lt;br /&gt;
&lt;br /&gt;
By extending the file_storage class and overriding methods, it is possible to change Moodle&#039;s file storage method to non-filesystem-based solutions (such as Amazon S3, etc).  Whilst this approach currently works, a new plugin type would allow this to be done without having to patch core.&lt;br /&gt;
&lt;br /&gt;
== Design ==&lt;br /&gt;
* New plugin type to go into a new directory called &amp;quot;storage&amp;quot;, eg. storage/filesystem/, storage/s3/.&lt;br /&gt;
* New abstract base class for file_storage and stored_file.  The methods should match the public and protected methods currently in file_storage and stored_file.&lt;br /&gt;
* The current file_storage and stored_file classes should move into a plugin, storage/filesystem/ and be made to extend the base class.&lt;br /&gt;
* A new admin configuration setting, $CFG-&amp;gt;storagemethod to be added which is set to one of the plugin names (&#039;filesystem&#039; by default).&lt;br /&gt;
* The get_file_storage() method in moodlelib should be modified to check $CFG-&amp;gt;storagemethod and to return an instance of the enabled storage plugin. The other code currently in get_file_storage() which does filesystem-specific checks should be moved into the storage/filesystem/ plugin&#039;s constructor.&lt;br /&gt;
* New section under Site Administration -&amp;gt; Plugins -&amp;gt; Storage can be used for configuring file storage plugins.&lt;br /&gt;
&lt;br /&gt;
== Code layout for storage plugins ==&lt;br /&gt;
* storage/&amp;lt;plugin&amp;gt;/lib.php:  should contain a class which extends the file_storage base class.&lt;br /&gt;
* plugins should also include a class which extends stored_file.  this can go in lib.php or in a separate file - it doesn&#039;t matter since the plugin&#039;s stored_file class only needs to be included/instantiated by its file_storage class&lt;br /&gt;
* plugins should also include a class which extends stored_file.  this can go in lib.php or in a separate file - it doesn&#039;t matter since the plugin&#039;s stored_file class only needs to be included/instantiated by its file_storage class.&lt;br /&gt;
&lt;br /&gt;
== Audit of all $CFG-&amp;gt;dataroot usage ==&lt;br /&gt;
An audit needs to be done of all usage of $CFG-&amp;gt;dataroot in core.  No code should write to dataroot if it is required to be readable on subsequent page requests.  It is OK to write to $CFG-&amp;gt;cachedir for caching purposes (ie. the data can be cleared at any point without causing problems) or $CFG-&amp;gt;tempdir for temp usage (temp files whos lifetime only spans a single script execution).  Any usage of $CFG-&amp;gt;dataroot for persistance should be replaced by a call to the storage API.&lt;br /&gt;
&lt;br /&gt;
Effected areas identified by the audit are:&lt;br /&gt;
* Custom language packs / language overrides: Currently these are stored in $CFG-&amp;gt;dataroot and need to be shared between hosts.  These need to move elsewhere (eg. database or storage API).&lt;br /&gt;
* Database module (mod/data/) presets: These are stored in $CFG-&amp;gt;dataroot/data/preset/ - they should be moved to a filearea/component in the storage API.&lt;br /&gt;
&lt;br /&gt;
== Third party plugins ==&lt;br /&gt;
The CONTRIB plugin review process should include an additional step to check for direct usage of $CFG-&amp;gt;dataroot.  Plugin developers should be encouraged to use the storage API so that users who are not using the filesystem storage method can use their plugin without bugs.&lt;br /&gt;
&lt;br /&gt;
== Migration between storage methods ==&lt;br /&gt;
A CLI script for migrating between storage methods should be added into admin/cli/.  There will be no need for storage plugins to implement their own migration routines as this can be implemented in the base class as follows:&lt;br /&gt;
* create an instance of the current file storage plugin ($fs = get_file_storage())&lt;br /&gt;
* also create an instance of the new plugin (eg. $newfs = new s3_file_storage())&lt;br /&gt;
* call the migrate() method: $fs-&amp;gt;migrate($newfs);&lt;br /&gt;
* the migrate method is implemented in the base class (doesnt need to be implemented in plugins). it does:&lt;br /&gt;
** SQL query: select distinct contenthash from mdl_files;&lt;br /&gt;
** for each result:&lt;br /&gt;
*** call $fs to retrieve contents of contenthash and store in a temp file (this will require a new method protected method to be added to the file_storage base class which needs to be implemented in each plugin). eg. $fs-&amp;gt;copy_contenthash_to($contenthash, $temppath);&lt;br /&gt;
*** call $newfs-&amp;gt;add_file_to_pool($temppath);&lt;br /&gt;
Note: this method of migration could be very slow for large sites, so advanced users may which to implement their own strategys for migration.&lt;/div&gt;</summary>
		<author><name>Ashleyholman</name></author>
	</entry>
</feed>