Moved ObjectCacheSessionHandler renewal logic to wfSetupSession()
authorAaron Schulz <aschulz@wikimedia.org>
Mon, 3 Aug 2015 20:35:50 +0000 (13:35 -0700)
committerOri.livneh <ori@wikimedia.org>
Mon, 10 Aug 2015 19:10:38 +0000 (19:10 +0000)
* This should trigger more reliably than the shutdown function
  callback, which is really only there for sanity to make sure
  session close/write happens.

Change-Id: I9a1aa76de121ba8de33b3fa850bd223929fae404

includes/GlobalFunctions.php
includes/objectcache/ObjectCacheSessionHandler.php

index f98a0cf..2b9bc25 100644 (file)
@@ -3461,8 +3461,9 @@ function wfResetSessionID() {
  * @param bool $sessionId
  */
 function wfSetupSession( $sessionId = false ) {
-       global $wgSessionsInMemcached, $wgSessionsInObjectCache, $wgCookiePath, $wgCookieDomain,
-                       $wgCookieSecure, $wgCookieHttpOnly, $wgSessionHandler;
+       global $wgSessionsInMemcached, $wgSessionsInObjectCache, $wgSessionHandler;
+       global $wgCookiePath, $wgCookieDomain, $wgCookieSecure, $wgCookieHttpOnly;
+
        if ( $wgSessionsInObjectCache || $wgSessionsInMemcached ) {
                ObjectCacheSessionHandler::install();
        } elseif ( $wgSessionHandler && $wgSessionHandler != ini_get( 'session.save_handler' ) ) {
@@ -3470,6 +3471,7 @@ function wfSetupSession( $sessionId = false ) {
                # hasn't already been set to the desired value (that causes errors)
                ini_set( 'session.save_handler', $wgSessionHandler );
        }
+
        session_set_cookie_params(
                0, $wgCookiePath, $wgCookieDomain, $wgCookieSecure, $wgCookieHttpOnly );
        session_cache_limiter( 'private, must-revalidate' );
@@ -3478,9 +3480,14 @@ function wfSetupSession( $sessionId = false ) {
        } else {
                wfFixSessionID();
        }
+
        MediaWiki\suppressWarnings();
        session_start();
        MediaWiki\restoreWarnings();
+
+       if ( $wgSessionsInObjectCache || $wgSessionsInMemcached ) {
+               ObjectCacheSessionHandler::renewCurrentSession();
+       }
 }
 
 /**
index 1430dd8..8a7b298 100644 (file)
@@ -21,6 +21,8 @@
  * @ingroup Cache
  */
 
+use MediaWiki\Logger\LoggerFactory;
+
 /**
  * Session storage in object cache.
  * Used if $wgSessionsInObjectCache is true.
@@ -28,9 +30,6 @@
  * @ingroup Cache
  */
 class ObjectCacheSessionHandler {
-
-       const TTL_REFRESH_WINDOW = 600; // refresh if expiring in 10 minutes
-
        /**
         * Install a session handler for the current web request
         */
@@ -145,20 +144,33 @@ class ObjectCacheSessionHandler {
         * See the comment inside ObjectCacheSessionHandler::install for rationale.
         */
        static function handleShutdown() {
+               session_write_close();
+       }
+
+       /**
+        * Pre-emptive session renewal function
+        */
+       static function renewCurrentSession() {
                global $wgObjectCacheSessionExpiry;
 
+               // Once a session is at half TTL, renew it
+               $window = $wgObjectCacheSessionExpiry / 2;
+               $logger = LoggerFactory::getInstance( 'SessionHandler' );
+
                $now = microtime( true );
                // Session are only written in object stores when $_SESSION changes,
                // which also renews the TTL ($wgObjectCacheSessionExpiry). If a user
                // is active but not causing session data changes, it may suddenly
-               // as they view a form, blocking the first submission.
+               // expire as they view a form, blocking the first submission.
                // Make a dummy change every so often to avoid this.
-               if ( !isset( $_SESSION['wsExpiresUnix'] )
-                       || ( $now + self::TTL_REFRESH_WINDOW ) > isset( $_SESSION['wsExpiresUnix'] )
-               ) {
+               if ( !isset( $_SESSION['wsExpiresUnix'] ) ) {
                        $_SESSION['wsExpiresUnix'] = $now + $wgObjectCacheSessionExpiry;
-               }
 
-               session_write_close();
+                       $logger->info( "Set expiry for session " . session_id(), array() );
+               } elseif ( ( $now + $window ) > $_SESSION['wsExpiresUnix'] ) {
+                       $_SESSION['wsExpiresUnix'] = $now + $wgObjectCacheSessionExpiry;
+
+                       $logger->info( "Renewed session " . session_id(), array() );
+               }
        }
 }