SpecialVersion: Handle Closures in $wgHooks nicer
[lhc/web/wiklou.git] / includes / objectcache / ObjectCacheSessionHandler.php
index 24d2a22..1430dd8 100644 (file)
@@ -28,8 +28,8 @@
  * @ingroup Cache
  */
 class ObjectCacheSessionHandler {
-       /** @var array Map of (session ID => SHA-1 of the data) */
-       protected static $hashCache = array();
+
+       const TTL_REFRESH_WINDOW = 600; // refresh if expiring in 10 minutes
 
        /**
         * Install a session handler for the current web request
@@ -56,7 +56,6 @@ class ObjectCacheSessionHandler {
         */
        protected static function getCache() {
                global $wgSessionCacheType;
-
                return ObjectCache::getInstance( $wgSessionCacheType );
        }
 
@@ -70,14 +69,6 @@ class ObjectCacheSessionHandler {
                return wfMemcKey( 'session', $id );
        }
 
-       /**
-        * @param mixed $data
-        * @return string
-        */
-       protected static function getHash( $data ) {
-               return sha1( serialize( $data ) );
-       }
-
        /**
         * Callback when opening a session.
         *
@@ -107,29 +98,22 @@ class ObjectCacheSessionHandler {
         */
        static function read( $id ) {
                $data = self::getCache()->get( self::getKey( $id ) );
-
-               self::$hashCache = array( $id => self::getHash( $data ) );
-
-               return ( $data === false ) ? '' : $data;
+               if ( $data === false ) {
+                       return '';
+               }
+               return $data;
        }
 
        /**
         * Callback when writing session data.
         *
         * @param string $id Session id
-        * @param mixed $data Session data
+        * @param string $data Session data
         * @return bool Success
         */
        static function write( $id, $data ) {
                global $wgObjectCacheSessionExpiry;
-
-               // Only issue a write if anything changed (PHP 5.6 already does this)
-               if ( !isset( self::$hashCache[$id] )
-                       || self::getHash( $data ) !== self::$hashCache[$id]
-               ) {
-                       self::getCache()->set( self::getKey( $id ), $data, $wgObjectCacheSessionExpiry );
-               }
-
+               self::getCache()->set( self::getKey( $id ), $data, $wgObjectCacheSessionExpiry );
                return true;
        }
 
@@ -157,10 +141,24 @@ class ObjectCacheSessionHandler {
        }
 
        /**
-        * Shutdown function. See the comment inside ObjectCacheSessionHandler::install
-        * for rationale.
+        * Shutdown function.
+        * See the comment inside ObjectCacheSessionHandler::install for rationale.
         */
        static function handleShutdown() {
+               global $wgObjectCacheSessionExpiry;
+
+               $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.
+               // Make a dummy change every so often to avoid this.
+               if ( !isset( $_SESSION['wsExpiresUnix'] )
+                       || ( $now + self::TTL_REFRESH_WINDOW ) > isset( $_SESSION['wsExpiresUnix'] )
+               ) {
+                       $_SESSION['wsExpiresUnix'] = $now + $wgObjectCacheSessionExpiry;
+               }
+
                session_write_close();
        }
 }