r72940 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r72939‎ | r72940 | r72941 >
Date:23:19, 13 September 2010
Author:tparscal
Status:resolved (Comments)
Tags:
Comment:
* Changed the expiry time strategy, now treating any request to ResourceLoader::respond which does not contain a version parameter as an unversioned request which is responded to with a near-future maxage and smaxage, while those which do contain a version parameter are treated as versioned requests and responded to with a far-future maxage and smaxage.
* Added some release notes for ResourceLoader globals.
* Changed when OutputPage appends timestamps to style/script-only requests - now they are only made into versioned requests if the module is a ResourceLoaderWikiModule or a ResourceLoaderUserPreferencesModule - because they might be changed on-wiki and require immediate feedback. This would only affect logged-in users however, as cached pages will contain the latest version number as of the time they were generated. This strategy may need to be adjusted to work with ESI to add version parameters to everything all the time, but this at least presents a reasonable fallback in the event that ESI is not setup.
Modified paths:
  • /trunk/phase3/RELEASE-NOTES (modified) (history)
  • /trunk/phase3/includes/DefaultSettings.php (modified) (history)
  • /trunk/phase3/includes/OutputPage.php (modified) (history)
  • /trunk/phase3/includes/ResourceLoader.php (modified) (history)
  • /trunk/phase3/includes/ResourceLoaderContext.php (modified) (history)
  • /trunk/phase3/includes/ResourceLoaderModule.php (modified) (history)

Diff [purge]

Index: trunk/phase3/includes/ResourceLoaderContext.php
@@ -33,6 +33,7 @@
3434 protected $user;
3535 protected $debug;
3636 protected $only;
 37+ protected $version;
3738 protected $hash;
3839
3940 /* Methods */
@@ -49,6 +50,7 @@
5051 $this->user = $request->getVal( 'user' );
5152 $this->debug = $request->getBool( 'debug' ) && $request->getVal( 'debug' ) === 'true';
5253 $this->only = $request->getVal( 'only' );
 54+ $this->version = $request->getVal( 'version' );
5355
5456 // Fallback on system defaults
5557 if ( !$this->language ) {
@@ -63,7 +65,7 @@
6466 $this->skin = $wgDefaultSkin;
6567 }
6668 }
67 -
 69+
6870 public function getRequest() {
6971 return $this->request;
7072 }
@@ -96,6 +98,10 @@
9799 return $this->only;
98100 }
99101
 102+ public function getVersion() {
 103+ return $this->version;
 104+ }
 105+
100106 public function shouldIncludeScripts() {
101107 return is_null( $this->only ) || $this->only === 'scripts';
102108 }
@@ -111,7 +117,7 @@
112118 public function getHash() {
113119 return isset( $this->hash ) ?
114120 $this->hash : $this->hash = implode( '|', array(
115 - $this->language, $this->direction, $this->skin, $this->user, $this->debug, $this->only
 121+ $this->language, $this->direction, $this->skin, $this->user, $this->debug, $this->only, $this->version
116122 ) );
117123 }
118124 }
\ No newline at end of file
Index: trunk/phase3/includes/OutputPage.php
@@ -2302,14 +2302,25 @@
23032303 if ( $group === 'user' ) {
23042304 $query['user'] = $wgUser->getName();
23052305 }
2306 - $context = new ResourceLoaderContext( new FauxRequest( $query ) );
 2306+ // Users might change their stuff on-wiki like site or user pages, or user preferences; we need to find
 2307+ // the highest timestamp of these user-changable modules so we can ensure cache misses upon change
23072308 $timestamp = 0;
23082309 foreach ( $modules as $name ) {
2309 - if ( $module = ResourceLoader::getModule( $name ) ) {
2310 - $timestamp = max( $timestamp, $module->getModifiedTime( $context ) );
 2310+ $module = ResourceLoader::getModule( $name );
 2311+ if (
 2312+ $module instanceof ResourceLoaderWikiModule ||
 2313+ $module instanceof ResourceLoaderUserPreferencesModule
 2314+ ) {
 2315+ $timestamp = max(
 2316+ $timestamp,
 2317+ $module->getModifiedTime( new ResourceLoaderContext( new FauxRequest( $query ) ) )
 2318+ );
23112319 }
23122320 }
2313 - $query['version'] = wfTimestamp( TS_ISO_8601, round( $timestamp, -2 ) );
 2321+ // Add a version parameter if any of the modules were user-changable
 2322+ if ( $timestamp ) {
 2323+ $query['version'] = wfTimestamp( TS_ISO_8601, round( $timestamp, -2 ) );
 2324+ }
23142325 // Make queries uniform in order
23152326 ksort( $query );
23162327 // Automatically select style/script elements
Index: trunk/phase3/includes/ResourceLoader.php
@@ -24,6 +24,7 @@
2525 * Dynamic JavaScript and CSS resource loading system
2626 */
2727 class ResourceLoader {
 28+
2829 /* Protected Static Members */
2930
3031 // @var array list of module name/ResourceLoaderModule object pairs
@@ -188,6 +189,9 @@
189190 * @param $context ResourceLoaderContext object
190191 */
191192 public static function respond( ResourceLoaderContext $context ) {
 193+ global $wgResourceLoaderVersionedClientMaxage, $wgResourceLoaderVersionedServerMaxage;
 194+ global $wgResourceLoaderUnversionedServerMaxage, $wgResourceLoaderUnversionedClientMaxage;
 195+
192196 // Split requested modules into two groups, modules and missing
193197 $modules = array();
194198 $missing = array();
@@ -200,33 +204,31 @@
201205 }
202206 }
203207
204 - // Calculate the mtime and caching maxages for this request. We need this, 304 or no 304
 208+ // If a version wasn't specified we need a shorter expiry time for updates to propagate to clients quickly
 209+ if ( is_null( $context->getVersion() ) ) {
 210+ $maxage = $wgResourceLoaderUnversionedClientMaxage;
 211+ $smaxage = $wgResourceLoaderUnversionedServerMaxage;
 212+ }
 213+ // If a version was specified we can use a longer expiry time since changing version numbers causes cache misses
 214+ else {
 215+ $maxage = $wgResourceLoaderVersionedClientMaxage;
 216+ $smaxage = $wgResourceLoaderVersionedServerMaxage;
 217+ }
 218+
 219+ // To send Last-Modified and support If-Modified-Since, we need to detect the last modified time
205220 $mtime = 1;
206 - $maxage = PHP_INT_MAX;
207 - $smaxage = PHP_INT_MAX;
208 -
209221 foreach ( $modules as $name ) {
210222 $mtime = max( $mtime, self::$modules[$name]->getModifiedTime( $context ) );
211 - $maxage = min( $maxage, self::$modules[$name]->getClientMaxage() );
212 - $smaxage = min( $smaxage, self::$modules[$name]->getServerMaxage() );
213223 }
214224
215 - // Output headers
216 - if ( $context->getOnly() === 'styles' ) {
217 - header( 'Content-Type: text/css' );
218 - } else {
219 - header( 'Content-Type: text/javascript' );
220 - }
221 -
 225+ header( 'Content-Type: ' . ( $context->getOnly() === 'styles' ? 'text/css' : 'text/javascript' ) );
222226 header( 'Last-Modified: ' . wfTimestamp( TS_RFC2822, $mtime ) );
223 - $expires = wfTimestamp( TS_RFC2822, min( $maxage, $smaxage ) + time() );
224227 header( "Cache-Control: public, max-age=$maxage, s-maxage=$smaxage" );
225 - header( "Expires: $expires" );
 228+ header( 'Expires: ' . wfTimestamp( TS_RFC2822, min( $maxage, $smaxage ) + time() ) );
226229
227 - // Check if there's an If-Modified-Since header and respond with a 304 Not Modified if possible
 230+ // If there's an If-Modified-Since header, respond with a 304 appropriately
228231 $ims = $context->getRequest()->getHeader( 'If-Modified-Since' );
229 -
230 - if ( $ims !== false && wfTimestamp( TS_UNIX, $ims ) == $mtime ) {
 232+ if ( $ims !== false && $mtime >= wfTimestamp( TS_UNIX, $ims ) ) {
231233 header( 'HTTP/1.0 304 Not Modified' );
232234 header( 'Status: 304 Not Modified' );
233235 return;
Index: trunk/phase3/includes/DefaultSettings.php
@@ -1645,19 +1645,32 @@
16461646 $wgClockSkewFudge = 5;
16471647
16481648 /**
1649 - * Maximum time in seconds to cache resources served by the resource loader on
1650 - * the client side (e.g. in the browser cache).
 1649+ * Maximum time in seconds to cache versioned resources served by the resource
 1650+ * loader on the client side (e.g. in the browser cache).
16511651 */
1652 -$wgResourceLoaderClientMaxage = 30*24*60*60; // 30 days
 1652+$wgResourceLoaderVersionedClientMaxage = 30 * 24 * 60 * 60; // 30 days
16531653
16541654 /**
1655 - * Maximum time in seconds to cache resources served by the resource loader on
1656 - * the server side. This means Squid/Varnish but also any other public proxy
1657 - * cache between the client and MediaWiki.
 1655+ * Maximum time in seconds to cache versioned resources served by the resource
 1656+ * loader on the server side. This means Squid/Varnish but also any other public
 1657+ * proxy cache between the client and MediaWiki.
16581658 */
1659 -$wgResourceLoaderServerMaxage = 30*24*60*60; // 30 days
 1659+$wgResourceLoaderVersionedServerMaxage = 30 * 24 * 60 * 60; // 30 days
16601660
16611661 /**
 1662+ * Maximum time in seconds to cache unversioned resources served by the resource
 1663+ * loader on the client.
 1664+ */
 1665+$wgResourceLoaderUnversionedClientMaxage = 5 * 60; // 5 minutes
 1666+
 1667+/**
 1668+ * Maximum time in seconds to cache unversioned resources served by the resource
 1669+ * loader on the server. This means Squid/Varnish but also any other public
 1670+ * proxy cache between the client and MediaWiki.
 1671+ */
 1672+$wgResourceLoaderUnversionedServerMaxage = 5 * 60; // 5 minutes
 1673+
 1674+/**
16621675 * Enable data URL embedding (experimental). This variable is very temporary and
16631676 * will be removed once we get this feature stable.
16641677 */
Index: trunk/phase3/includes/ResourceLoaderModule.php
@@ -51,30 +51,6 @@
5252 }
5353
5454 /**
55 - * The maximum number of seconds to cache this module for in the
56 - * client-side (browser) cache. Override this only if you have a good
57 - * reason not to use $wgResourceLoaderClientMaxage.
58 - *
59 - * @return Integer: cache maxage in seconds
60 - */
61 - public function getClientMaxage() {
62 - global $wgResourceLoaderClientMaxage;
63 - return $wgResourceLoaderClientMaxage;
64 - }
65 -
66 - /**
67 - * The maximum number of seconds to cache this module for in the
68 - * server-side (Squid / proxy) cache. Override this only if you have a
69 - * good reason not to use $wgResourceLoaderServerMaxage.
70 - *
71 - * @return Integer: cache maxage in seconds
72 - */
73 - public function getServerMaxage() {
74 - global $wgResourceLoaderServerMaxage;
75 - return $wgResourceLoaderServerMaxage;
76 - }
77 -
78 - /**
7955 * Get whether CSS for this module should be flipped
8056 */
8157 public function getFlip( $context ) {
@@ -1013,14 +989,6 @@
1014990 return $this->modifiedTime[$hash];
1015991 }
1016992
1017 - public function getClientMaxage() {
1018 - return 300; // 5 minutes
1019 - }
1020 -
1021 - public function getServerMaxage() {
1022 - return 300; // 5 minutes
1023 - }
1024 -
1025993 public function getFlip( $context ) {
1026994 global $wgContLang;
1027995
Index: trunk/phase3/RELEASE-NOTES
@@ -54,7 +54,14 @@
5555 $wgUseMemCached, $wgDisableSearchContext, $wgColorErrors,
5656 $wgUseZhdaemon, $wgZhdaemonHost and $wgZhdaemonPort.
5757 * (bug 24408) The include_path is not modified in the default LocalSettings.php
58 -* $wgVectorExtraStyles has been removed, and is no longer in use.
 58+* $wgVectorExtraStyles was removed, and is no longer in use.
 59+* $wgLoadScript was added to specify alternative locations for ResourceLoader
 60+ requests.
 61+* $wgResourceLoaderVersionedClientMaxage, $wgResourceLoaderVersionedServerMaxage,
 62+ $wgResourceLoaderUnversionedClientMaxage and
 63+ wgResourceLoaderUnversionedServerMaxage were added to specify maxage and
 64+ smaxage times for responses from ResourceLoader based on whether the request's
 65+ URL contained a version parameter or not.
5966
6067 === New features in 1.17 ===
6168 * (bug 10183) Users can now add personal styles and scripts to all skins via

Follow-up revisions

RevisionCommit summaryAuthorDate
r73388Fixed issues in r72940 - missing $ in release notes and remnant of ResourceLo...tparscal17:54, 20 September 2010
r74146Fix logic error in IMS check introduced in r72940. Was sending 304 even for m...nikerabbit16:54, 2 October 2010

Comments

#Comment by Platonides (talk | contribs)   15:09, 20 September 2010
+$module instanceof ResourceLoaderUserPreferencesModule

There's no such class.


wgResourceLoaderUnversionedServerMaxage misses the $ in RELEASE NOTES.


Instead of those overly long variables name, I would prefer to use oneor two rray variables. Eg.

$wgResourceLoaderMaxage = array ( 'versioned'=> array( 'client' => 30*24*60*60, 'server' => 30*24*60*60 ), 'unversioned' => 300 );

Note that I am accepting an int as the value for both array items.

#Comment by Trevor Parscal (WMF) (talk | contribs)   17:55, 20 September 2010

Fixed most of this in r73388. As for the array format of the globals - I do not dissagree that this would be nice, I will run this by Roan (who made the original 2 that I split into 4)

#Comment by Catrope (talk | contribs)   13:31, 1 October 2010
+* $wgLoadScript was added to specify alternative locations for ResourceLoader
+  requests.
+* $wgResourceLoaderVersionedClientMaxage, $wgResourceLoaderVersionedServerMaxage,
+  $wgResourceLoaderUnversionedClientMaxage and
+  wgResourceLoaderUnversionedServerMaxage were added to specify maxage and
+  smaxage times for responses from ResourceLoader based on whether the request's
+  URL contained a version parameter or not.

None of these things belong in the 1.17 release notes, because the resource loader is new in 1.17.

#Comment by 😂 (talk | contribs)   13:32, 1 October 2010

New configuration items are always added to RELEASE-NOTES?

#Comment by Catrope (talk | contribs)   13:34, 1 October 2010

Alright, fine, but let's at least group all resource loader-related release notes entries then.

#Comment by Trevor Parscal (WMF) (talk | contribs)   17:28, 1 October 2010

What's the problem here? Why is this marked fixme? Looks resolved to me.

#Comment by Catrope (talk | contribs)   17:30, 1 October 2010

Neither you nor the reporter ever set it back to new. Have now set this to resolved.

Status & tagging log